每个 HTTP 请求的 Angular 显示微调器,代码更改非常少

标签 angular http

我正在开发一个现有的 Angular 应用程序。版本是 Angular 4。

应用程序从许多不同的组件对 REST API 进行 HTTP 调用。

我想为每个 HTTP 请求显示一个自定义微调器。由于这是一个现有的应用程序,因此有很多地方可以调用 REST API。而且处处改代码也不是一个可行的选择。

我想实现一个抽象的解决方案来解决这个问题。

如果有任何选择,请提出建议。

最佳答案

@jornare 在他的解决方案中有一个好主意。他正在处理多个请求的案例。然而,代码可以写得更简单,无需创建新的可观察对象并将请求存储在内存中。下面的代码还使用了 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(() => {
        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) {}
}

关于每个 HTTP 请求的 Angular 显示微调器,代码更改非常少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49385369/

相关文章:

ruby-on-rails - 如何在 Ruby 中获取 http 请求的内容?

angular - Ionic 4 Angular 8-未捕获的ReferenceError : global is not defined

angular - Travis CI 构建失败 - (Aws::S3::Errors::SignatureDoesNotMatch)

angular - formbuilder 的 patchvalue 或 setvalue 不会将字段标记为脏或已触摸

javascript - Angular 7 - promise 内的 forEach 迭代在 promise 解决后执行。为什么?

performance - Go http 服务器基准测试性能慢

javascript - 如何将数据发布到 Node 服务器并从中获取响应文本?

Angular http获取数据

rest - 使用其余客户端的PUT映射错误elasticsearch:无法解析映射[_doc]:根映射定义具有不受支持的参数:

angular - 如何修复浏览器未捕获错误 : Script error for "@ng-bootstrap/ng-bootstrap" ng-boostrap Bazel