【发布时间】:2022-02-02 17:23:15
【问题描述】:
如何避免角加载拦截器中的多次加载 在角度每个http调用加载微调器并尝试仅实现一个加载用于初始页面加载。如何解决这个问题
【问题讨论】:
标签: javascript angular angular-http angular-http-interceptors
如何避免角加载拦截器中的多次加载 在角度每个http调用加载微调器并尝试仅实现一个加载用于初始页面加载。如何解决这个问题
【问题讨论】:
标签: javascript angular angular-http angular-http-interceptors
您正在处理现有的 Angular 应用程序。
应用程序从许多不同的组件对 REST API 进行 HTTP 调用。
您希望为每个 HTTP 请求显示一个自定义微调器。由于这是一个现有的应用程序,因此有很多地方调用了 REST API。而且在每个地方一个一个地更改代码不是一个可行的选择。
所以,你想实现一个抽象的解决方案来解决这个问题。
代码可以写得更简单,无需创建新的 observable 并将请求存储在内存中。下面的代码也使用带有管道操作符的 RxJS 6:
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpInterceptor,
HttpResponse
} from '@angular/common/http';
import { finalize } from 'rxjs/operators';
import { LoadingService } from '@app/services/loading.service';
import { of } from 'rxjs';
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
private totalRequests = 0;
constructor(private loadingService: LoadingService) { }
intercept(request: HttpRequest<any>, next: HttpHandler) {
this.totalRequests++;
this.loadingService.setLoading(true);
return next.handle(request).pipe(
finalize(res => {
this.totalRequests--;
if (this.totalRequests === 0) {
this.loadingService.setLoading(false);
}
})
);
}
}
将此拦截器服务添加到您的模块提供程序中:
@NgModule({
// ...
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true }
]
})
export class AppModule { }
这是LoadingService 实现的示例:
@Injectable()
export class LoadingService {
private isLoading$$ = new BehaviorSubject<boolean>(false);
isLoading$ = this.isLoading$$.asObservable();
setLoading(isLoading: boolean) {
this.isLoading$$.next(isLoading);
}
}
下面是在组件中使用 LoadingService 的方法:
@Component({
selector: 'app-root',
template: `
<ng-container *ngIf="loadingService.isLoading$ | async">
<i class="loading"></i>
</ng-container>
<router-outlet></router-outlet>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
constructor(public loadingService: LoadingService) {}
}
【讨论】: