首页 > 解决方案 > 我试图在请求完成时通知观察者以停止显示加载微调器

问题描述

我通过注入我创建的 loadIndicatorService 的拦截器拦截请求,它工作正常,但是当我在 ngOnInit 中加载用户时,LoadIndicator 将请求视为即时请求,代码如下:

    @Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
  constructor( private loadingIndicatorService: LoadingIndicatorService) { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    this.loadingIndicatorService.onStarted(request);

    const currentUser = localStorage.getItem('token');

      request = request.clone({
        url: `${environment.apiURL}/${environment.apiVersion}/${request.url}`,
        setHeaders: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${currentUser}`
        }
      });

    return next.handle(request).finally(() => this.loadingIndicatorService.onFinished(request));

  }
}

和服务:

    @Injectable({
    providedIn: 'root'
  })
export class LoadingIndicatorService {

  onLoadingChanged: EventEmitter<boolean> = new EventEmitter<boolean>();

  /**
   * Stores all currently active requests
   */
  private requests: HttpRequest<any>[] = [];

  /**
   * Adds request to the storage and notifies observers
   */
  onStarted(req: HttpRequest<any>): void {
    this.requests.push(req);
    this.notify();
  }

  /**
   * Removes request from the storage and notifies observers
   */
  onFinished(req: HttpRequest<any>): void {
    const index = this.requests.indexOf(req);
    if (index !== -1) {
      this.requests.splice(index, 1);
    }
    this.notify();
  }

  /**
   * Notifies observers about whether there are any requests on fly
   */
  private notify(): void {
    this.onLoadingChanged.emit(this.requests.length !== 0);
  }
}

标签: angularhttprequestinterceptor

解决方案


我建议创建一个广播加载状态的服务,并且加载微调器组件会观察到该服务。每个操作/请求都将使用此服务更新加载状态。

一个例子:



@Injectable()
export class LoaderService {
  private loaderSubject = new Subject<boolean>();

  constructor() {}

  show() {
    this.loaderSubject.next(true);
  }

  hide() {
    this.loaderSubject.next(false);
  }

  select(): Observable<boolean>{
    return this.loaderSubject.asObservable();
  }
}

微调器组件:


@Component({
  selector: 'app-loader',
  template: 'YOUR SPINNER'
})
/**
 * Loader Component to show a spinner when the state's show equals to true
 *
 */
export class LoaderComponent implements OnDestroy, OnInit {
  show = false;
  private subscription: Subscription;

  constructor(private loaderService: LoaderService) {}

  ngOnInit() {
    this.subscription = this.loaderService.select().subscribe(
      (state: boolean) => {
        this.show = state;
      }
    );
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

你的拦截器:


@Injectable()
export class AppHttpInterceptor implements HttpInterceptor { 

constructor( private loader: LoaderService) { } 

intercept(request: HttpRequest, next: HttpHandler): Observable> {
  this.loadingIndicatorService.show();

  const currentUser = localStorage.getItem('token');

  request = request.clone({
    url: `${environment.apiURL}/${environment.apiVersion}/${request.url}`,
    setHeaders: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${currentUser}`
    }
  });

  return next.handle(request).finally(() => this.loading.hide());
  } 
}


推荐阅读