在组件中注入 http 拦截器
Inject http interceptor at component
我创建了这个 http 拦截器:
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
public my_status: boolean = true;
private _statusChange: Subject<boolean> = new Subject<boolean>();
public statusChange$ = this._statusChange.asObservable();
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.changeStatus(false);
const my_req = req.clone({
url: API_PATH + req.url
});
return next
.handle(my_req)
.do(event => {
if (event instanceof HttpResponse)
this.changeStatus(true);
});
}
private changeStatus(status: boolean) {
this.my_status = status;
this._statusChange.next(this.my_status);
}
}
在我的组件中,我做到了:
export class AppComponent implements OnInit {
public my_status: boolean;
constructor(private httpInterceptor: NoopInterceptor) {
this.my_status = httpInterceptor.my_status;
httpInterceptor.statusChange$.subscribe(this.changeStatus);
}
changeStatus(status: boolean) {
this.my_status = status;
}
}
在app.module
,我提供了这样的拦截器:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: NoopInterceptor,
multi: true
}
]
当我按照上面的方式执行时,我得到 No provider for NoopInterceptor!
,因为我没有提供 NoopInterceptor
,但是如果我像这样提供 NoopInterceptor
:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: NoopInterceptor,
multi: true
},
NoopInterceptor
]
我再打两次,组件打错了,那我就订阅不了了statusChange
。我该如何解决这个问题?
您是否尝试过将 NoopInterceptor 放在 HTTP_INTERCEPTOR 和 useExisting 而不是 useClass 的提供之前?
这样你应该只得到一个 NoopInterceptor 实例。
有可能创建单个拦截器实例:
providers: [
NoopInterceptor,
{
provide: HTTP_INTERCEPTORS,
useExisting: NoopInterceptor,
multi: true
}
]
但是加载指示器状态的正确解决方案(我猜 statusChange
用于此目的)是将其与拦截器分离并使其成为单独的提供者。
并且如图所示 ,应该有请求计数器,因为可以有同时请求,并且它应该受到成功和错误 do
回调的影响。
我创建了这个 http 拦截器:
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
public my_status: boolean = true;
private _statusChange: Subject<boolean> = new Subject<boolean>();
public statusChange$ = this._statusChange.asObservable();
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.changeStatus(false);
const my_req = req.clone({
url: API_PATH + req.url
});
return next
.handle(my_req)
.do(event => {
if (event instanceof HttpResponse)
this.changeStatus(true);
});
}
private changeStatus(status: boolean) {
this.my_status = status;
this._statusChange.next(this.my_status);
}
}
在我的组件中,我做到了:
export class AppComponent implements OnInit {
public my_status: boolean;
constructor(private httpInterceptor: NoopInterceptor) {
this.my_status = httpInterceptor.my_status;
httpInterceptor.statusChange$.subscribe(this.changeStatus);
}
changeStatus(status: boolean) {
this.my_status = status;
}
}
在app.module
,我提供了这样的拦截器:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: NoopInterceptor,
multi: true
}
]
当我按照上面的方式执行时,我得到 No provider for NoopInterceptor!
,因为我没有提供 NoopInterceptor
,但是如果我像这样提供 NoopInterceptor
:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: NoopInterceptor,
multi: true
},
NoopInterceptor
]
我再打两次,组件打错了,那我就订阅不了了statusChange
。我该如何解决这个问题?
您是否尝试过将 NoopInterceptor 放在 HTTP_INTERCEPTOR 和 useExisting 而不是 useClass 的提供之前? 这样你应该只得到一个 NoopInterceptor 实例。
有可能创建单个拦截器实例:
providers: [
NoopInterceptor,
{
provide: HTTP_INTERCEPTORS,
useExisting: NoopInterceptor,
multi: true
}
]
但是加载指示器状态的正确解决方案(我猜 statusChange
用于此目的)是将其与拦截器分离并使其成为单独的提供者。
并且如图所示 do
回调的影响。