您可以为此使用 HTTP 拦截器。 HTTP 拦截器作为中间件组件工作,您可以在每次发出请求时挂钩。这个想法是,您将在发出请求时增加一个计数器,并在请求完成(成功或失败)时减少它。
当计数器为 0 时,不显示加载器。当计数器大于 0 时,显示一个加载器。
对于加载器组件本身,您可以编写一个服务来监听计数器的变化,并使用数据绑定在正确的时间显示微调器。
request.interceptor.ts
import { HttpInterceptor } from '@angular/common/http';
import { HttpRequest } from "@angular/common/http";
import { Observable } from "rxjs/Observable";
import { HttpHandler, HttpEvent } from "@angular/common/http";
import 'rxjs/add/operator/finally'
import { HttpMonitor } from "../request-spinner/http.monitor";
export class RequestHttpInterceptor implements HttpInterceptor {
constructor(private httpMonitor: HttpMonitor){
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.httpMonitor.addRequest();
return next.handle(req).finally(() => {
this.httpMonitor.removeRequest();
})
}
}
http.monitor.ts
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class HttpMonitor {
public pendingRequestNumber: number;
public pendingRequests:Observable<number>;
private prSubject: BehaviorSubject<number>;
constructor() {
this.prSubject = new BehaviorSubject<number>(0);
this.pendingRequests = this.prSubject.asObservable();
this.pendingRequestNumber = 0;
}
addRequest() {
this.prSubject.next(++this.pendingRequestNumber)
}
removeRequest() {
this.prSubject.next(--this.pendingRequestNumber)
}
}
spinner.component.ts
import { Component } from "@angular/core";
import { HttpMonitor } from './http.monitor';
@Component({
selector: '[spinner]',
template: `
<img *ngIf="httpMonitor.pendingRequestNumber >0" src="http://www.silkron.co.uk/images/spinner.gif" />
`,
styles: [
`
img {
width: 20px;
height: 20px;
}
`
]
})
export class SpinnerComponent {
constructor(public httpMonitor:HttpMonitor){
}
}
app.module.ts
import { HttpClientModule } from "@angular/common/http";
...
@NgModule({
imports: [BrowserModule, HttpClientModule],
declarations: [SpinnerComponent],
exports: [],
providers: [
HttpMonitor,
{
provide: HTTP_INTERCEPTORS,
useClass: RequestHttpInterceptor,
multi: true,
},
],
bootstrap: [AppComponent]
})
export class AppModule {
}