【问题标题】:Synchronize changes of service variable that changes in time angular 10同步随时间变化的服务变量的变化 angular 10
【发布时间】:2020-09-29 23:35:56
【问题描述】:

我正在尝试使用Angular 10 中的以下服务,这是一个查找正在进行的 http 请求的服务,如果有 http 请求,此服务会从 true 变为 false,这很好,我检查一下控制台日志

export class SpinnerService implements HttpInterceptor {

  public loading: boolean = false;
  
  constructor() {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.loading = true;
    // console.log('estado spinner: >> ', this.loading);
    return next.handle(req).pipe(
      finalize(() => {
        this.loading = false; 
        // console.log('todas solicitudes ok');
        console.log('estado espinner: >>', this.loading);
      })
    );
  }
}

当我尝试在另一个组件中使用该服务时,我遇到了问题,因为该服务未与该组件的本地变量同步。 例如,服务的加载变量开始为假,然后变为真,然后在 5 秒的时间内变为假,这需要 API 的其余部分带来数据。

加载变量最初与加载变量同步为false,但随后不跟随加载变量的状态,加载变量保持为false

如何同步这些变量?请帮忙,我不知道如何搜索

这是我从加载变量调用服务的构造函数,

public carga = this._spinnerService.loading;
    
constructor(private _spinnerService: SpinnerService) 
{
  this.crearFormulario();  // inicializar formulario
  // this._spinnerService.loading = this.spinneres;
  // console.log('estado inicial spinner: >>', this._spinnerService.loading);
  console.log('estado inicial spinner: >>', this.carga);
} 

【问题讨论】:

  • 好的,在拦截函数内部将值设置为 true。一旦任何 http 请求返回,它就会被设置为 false。问题是它处理了多少请求,时差是多少?很有可能它发生得如此之快,以至于除了可能 50 毫秒之外,从未见过真正的价值。或更少。哟克里奥阙
  • 这可能是由于您对服务范围的限制。您的服务将拦截所有网络请求并应用您输入的逻辑。例如,如果您有 2 个 api 调用,当您进行第一次调用时,拦截器将值设置为 true,然后在 finalize 中将其设置为 false,同样会第二个请求也会发生。所以你不能保证 this.loading 会像你期望的那样运行。
  • 这个 SpinnerService 的范围是什么,可能是提供给组件级别而不是模块。以便它为每个组件创建一个自身的实例,从而为每个组件附加加载变量。这与依赖注入有关

标签: angular service constructor synchronized angular-http-interceptors


【解决方案1】:

我认为您试图展示的是从您的应用程序进行的每个 http 网络调用的微调器。如果是这种情况,您几乎是正确的,除了您在 SpinnerService 类中提到的公共变量“加载”。

import { NgxSpinnerService } from 'ngx-spinner';
export class SpinnerService implements HttpInterceptor{
            
    constructor(private spinner: NgxSpinnerService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    {
        this.spinner.show();
        return next.handle(req).pipe(
            finalize(() => {
                        this.spinner.hide();
                    }
            )
    );
    }
}

请安装

npm i ngx-spinner

在你的 app.component.ts 中

<ngx-spinner></ngx-spinner>

请参考:

https://www.npmjs.com/package/ngx-spinner

【讨论】:

  • muchas gracias por Competitionas, se puede hacer de esa manera, pero no me gustan muchas las dependencias ngx
【解决方案2】:

我能够解决这个问题,我在同一个 ts 文件中创建了类,以便它更有序,一个类负责拦截逻辑,另一个类负责监听 http 请求,我检查了许多解决方案,但这是我最喜欢的一个,因为它无需使用依赖项即可向 html 返回 true 或 false。

这是您使用的服务的 ts 文件,您只需在要使用微调器的组件中导入服务即可。

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';//para interceptor de http
import { BehaviorSubject, Observable } from 'rxjs';//para interceptor de http
import { tap } from 'rxjs/operators';//para interceptor de http


@Injectable({
  providedIn: 'root'
})

//servicio interceptor que escucha si hay solicitudes http en progreso
export class interceptHttpService implements HttpInterceptor{

  constructor(private _pruebaspinerss3 : spinnerService ) { }
  
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
  {    
    this._pruebaspinerss3.requestStarted();    
    return this.handler(next,request);
  }

  handler(next ,request)
  {
    return next.handle(request)
      .pipe(
          tap(
            (event) =>{
              if (event instanceof HttpResponse){
                this._pruebaspinerss3.requestEnded();  
              }
            },
            (error: HttpErrorResponse) =>{
              this._pruebaspinerss3.resetSpinner();
              throw error;
            }
          ),
      )
  };
}

export class spinnerService{
  
  private count = 0;
  private spinner$ = new BehaviorSubject<string>('');
  
  getSpinnerObserver(): Observable<string>{
    return this.spinner$.asObservable();
  }  

  requestStarted() {
    console.log('spinner activado');   
    if (++this.count === 1) {
      this.spinner$.next('start');
    }
  }

  requestEnded() {
    console.log('spinner desactivado');   
    if (this.count === 0 || --this.count === 0) {
      this.spinner$.next('stop');
    }
  }

  resetSpinner() {
    console.log('error en solicitud, reset spinner');
    this.count = 0;
    this.spinner$.next('stop');
  }
}

在 app.module ts 文件中

import { interceptHttpService, spinnerService } from './services/spinner.service';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2021-05-24
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多