angular - 在 Angular 6 中创建通用 Http 服务包装器好不好
问题描述
我创建了一个通用的 http 服务包装器,并将它注入到每个组件中。我有点困惑的是,
是在每个组件中注入 HttpClient 服务还是像我创建的那样创建一个 http 服务包装器更好?
或者我们可以两者都做?
请对此提出一些建议。这将非常有帮助。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { LoaderService } from './loader.service';
import { FormUtils } from '../utils/form.utils';
@Injectable({
providedIn: 'root'
})
export class HttpService {
private apiUrl: string;
constructor(private http: HttpClient, private _loaderService: LoaderService) {
this.apiUrl = environment.url;
}
post<T>(url, data, loader = true): Observable<Common.ApiResponse<T>> {
if (loader) {
this._loaderService.loader.next(loader);
}
return this.http.post<Common.ApiResponse<T>>(this.apiUrl + url, data);
}
put<T>(url, data, loader = true): Observable<Common.ApiResponse<T>> {
if (loader) {
this._loaderService.loader.next(loader);
}
return this.http.put<Common.ApiResponse<T>>(this.apiUrl + url, data);
}
patch<T>(url, data, loader = true): Observable<Common.ApiResponse<T>> {
if (loader) {
this._loaderService.loader.next(loader);
}
return this.http.patch<Common.ApiResponse<T>>(this.apiUrl + url, data);
}
get<T>(
url,
httpParams?: any,
loader = true
): Observable<Common.ApiResponse<T>> {
const updatedParams = this.parseDateToTimeStamp(httpParams);
console.log(updatedParams, '--------------');
if (loader) {
this._loaderService.loader.next(loader);
}
for (let item in httpParams) {
if (
httpParams[item] === '' ||
httpParams[item] === undefined ||
httpParams[item] === null
) {
delete httpParams[item];
}
}
const header = {};
if (httpParams) {
header['params'] = updatedParams;
}
return this.http.get<Common.ApiResponse<T>>(this.apiUrl + url, header);
}
parseDateToTimeStamp(obj: any) {
const newValueInstance = Object.assign({}, obj);
(function isEmpty(data: any): boolean {
if (typeof data === 'object' && data !== null) {
if (Array.isArray(data)) {
data.forEach((item: any, index: number) => {
if (isEmpty(item)) {
data.splice(index, 1);
}
});
} else {
Object.keys(data).map((key, index) => {
console.log(data[key] instanceof Date);
if (data[key] instanceof Date) {
data[key] = new Date(data[key]).getTime();
}
});
}
}
return data;
})(newValueInstance);
return newValueInstance;
}
}
解决方案
除非您知道自己在做什么,否则我真的不建议您这样做...
此外,如果您只是为加载器服务创建此包装器服务。考虑改用角度拦截器。拦截器将检测何时发出 http 请求并显示您的加载程序。阅读这篇中等文章/指南:Angular 6 中每个 HTTP 请求的加载器栏
目前,您的“包装器”仅允许将 url 链接、HttpParams、正文和加载器变量作为参数传入。当您必须集成需要特定HttpHeaders
设置或具有不同responseType
(如“文本”)的其他 API 端点时,您将开始面临问题。您最终不得不一次又一次地修改您的包装服务,并且浪费大量时间来保存几行代码。
或者您可能只是尝试做一个简单的 get 请求而不想调用parseDateToTimeStamp()
. 你不能用你的wrapper service做到这一点。
或者,如果您想HEAD
提出请求,那么您最终将不得不修改您的包装服务,或者在您的应用程序中混合使用包装服务和原始HttpClient
包,这只是代码异味。
你最好直接使用 HttpClient 包。
相反,您可以创建一个新的 .ts 文件,可能将其命名为DateTimeHelper.ts
或其他名称,然后将其导出parseDateToTimeStamp()
,如下所示:
export function parseDateToTimeStamp(){}
然后将此功能导入您需要使用的任何服务功能中。
在这样做时,您还需要将代码的以下部分抽象为一个单独的函数(类似这样):
export function updateMyParams(httpParams: HttpParams){ //or some identifier that you prefer
const updatedParams = this.parseDateToTimeStamp(httpParams);
console.log(updatedParams, '--------------');
if (loader) {
this._loaderService.loader.next(loader);
}
for (let item in httpParams) {
if (
httpParams[item] === '' ||
httpParams[item] === undefined ||
httpParams[item] === null
) {
delete httpParams[item];
}
}
const header = {};
if (httpParams) {
header['params'] = updatedParams;
}
}
您只需要为您需要使用它的服务重新导入这两个功能。
推荐阅读
- python - 龙卷风:初始化()和准备()之间的区别
- python - 在 mac os 和 python 中设置 SIGKILL 处理程序时出现 OSError
- c# - 如何通过cmd运行多个specflow项目?
- ios - 带有 Firebase iOS 云消息通知的 Amazon SNS 不起作用
- amazon-s3 - 公开 AWS CodeBuild 工件
- python - 根据另一列中的 ID 列表替换一列的值
- amazon-web-services - 获取 Terraform Code 和 AWS / Cloud 之间的区别
- javascript - 使用jquery动态设置数据属性的问题
- javascript - 将 mongodb 从 Heroku 转移到 localhost 后的 JS 加载问题
- c# - 依赖注入 ILoggerFactory,中间件中的 ILogger,记录器未执行