Angular 6主题订阅无法正常运行

时间:2018-08-13 12:54:23

标签: javascript angular typescript observable reactivex

我有一个http interceptor,它在请求开始和结束时都会发出“字符串”:

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

  private loadingIndicatorSource = new  Subject<string>();
  private loadingIndicator$ = this.loadingIndicatorSource.asObservable();

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.updateVisibility('block');
    return next.handle(req)
      .pipe(
        finalize(
          () => {
            this.updateVisibility('none');
          }
        )
      )
      ;
  }

  updateVisibility(state: string) {
    this.loadingIndicatorSource.next(state);
  }

  getLoadingIndicator() {
    return this.loadingIndicator$;
  }
}

这是我注入服务的组件:

export class AppComponent {


  display = 'none';

  constructor(public  authenticationService: AuthenticationService,
              public loadingIndicatorService: LoadingIndicatorService) {
    this.loadingIndicatorService.getLoadingIndicator().subscribe(visibility => {
      console.log(visibility);
      this.display = visibility;
    });

    }
  }

实际上,我正在尝试显示加载指示器:

 <div [style.display]="display">
    <mat-progress-bar mode="indeterminate" color="warn" ></mat-progress-bar>
  </div>

我从Angular官方网站上获得了this教程。

但是subscribe方法从不执行。

为什么订阅方法不起作用?

1 个答案:

答案 0 :(得分:3)

我要做的是创建一个SpinnerService和一个SpinnerInterceptor,而不是将它们合并在一起。

让Spinner服务分配未完成的请求量,并在未完成的请求大于0时显示Spinner。

@Injectable()
export class SpinnerService {
    private requestAmount$ = new BehaviorSubject(0);

public showSpinner$ = this.requestAmount$.asObservable().pipe(map(r => r > 0));

requestStart() {
    this.requestAmount$.next(this.requestAmount$.getValue() + 1);
}

requestEnd() {
    this.requestAmount$.next(this.requestAmount$.getValue() - 1);
}
}

在您的spinnerInterceptor内部,您可以注入SpinnerService并根据每个请求对其进行更新。

@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
    constructor(private spinnerService: SpinnerService) {}

intercept(req: HttpRequest<any>, next: HttpHandler) {
        this.spinnerService.requestStart();

        return next.handle(req).pipe(
            finalize(() => {
                this.spinnerService.requestEnd();
            })
        );
    }
}

在您的应用程序组件内部使用ngOnInit钩子,请不要使用违反样式指南的构造函数。

export class AppComponent implements OnInit{


  display = 'none';

  constructor(public  authenticationService: AuthenticationService,
              public spinnerService: SpinnerService) {}
ngOnInit(){
    this.spinnerService.showSpinner$.subscribe(visibility => {
      console.log(visibility);
      this.display = visibility ? 'block': 'none';
    });

    }
  }

分离使阅读和理解变得更加容易。

希望这对您有帮助!