Cómo evitar la carga múltiple en el interceptor de carga angular En angular, cada girador de carga de llamadas http e intentó implementar solo una carga para la carga inicial de la página. como solucionar esto
Está trabajando en una aplicación Angular existente.
La aplicación realiza llamadas HTTP a una API REST desde varios componentes.
Desea mostrar un control giratorio personalizado para cada solicitud HTTP. Dado que esta es una aplicación existente, hay muchos lugares donde se realizan llamadas a la API REST. Y cambiar el código uno por uno en todos los lugares no es una opción factible.
Entonces, le gustaría implementar una solución abstracta que resuelva este problema.
El código podría escribirse de manera más simple, sin crear nuevas solicitudes observables y de almacenamiento en la memoria. El siguiente código también usa RxJS 6 con operadores canalizables:
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); } }) ); } }Agregue este servicio de interceptor a sus proveedores de módulos:
@NgModule({ // ... providers: [ { provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true } ] }) export class AppModule { } Aquí hay un ejemplo de la implementación de LoadingService :
@Injectable() export class LoadingService { private isLoading$$ = new BehaviorSubject<boolean>(false); isLoading$ = this.isLoading$$.asObservable(); setLoading(isLoading: boolean) { this.isLoading$$.next(isLoading); } } Y así es como usaría LoadingService en un componente:
@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) {} }