我有很多需要从Web服务加载数据的组件。在加载过程中,我想显示一个覆盖整个站点的全局加载指示器。多个组件可能同时加载数据。
为了同步一个常见的加载指示器我编写了一个服务:
import { Observable } from "rxjs/Observable";
import { Observer } from "rxjs/Observer";
import { Injectable } from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class GlobalLoadingIndicatorService {
private _isLoadingSource = new BehaviorSubject<boolean>(false);
public isLoadingObservable = this._isLoadingSource.asObservable();
public get isLoading(): boolean{
return this._loadingProcessCount > 0;
}
private _loadingProcessCount: number = 0;
public addLoadingProcess(): void{
this._loadingProcessCount += 1;
this._isLoadingSource.next(this.isLoading);
}
public removeLoadingProcess(): void{
this._loadingProcessCount -= 1;
if(this._loadingProcessCount < 0){
throw "Negative _loadingProcessCount is not possible.";
}
this._isLoadingSource.next(this.isLoading);
}
}
在我的AppComponent
(它是我的应用的根目录)中,我将Observable<boolean>
存储在了一个属性isLoadingObservable
中:
import { Component, OnDestroy, OnInit } from "@angular/core";
import { GlobalLoadingIndicatorService } from "../Services/GlobalLoadingIndicatorService.js";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs";
@Component({
selector: "app",
templateUrl: "/Templates/App"
})
export class AppComponent implements OnInit{
constructor(
private _globalLoadingIndicatorService: GlobalLoadingIndicatorService
) { }
public isLoadingObservable: Observable<boolean>;
ngOnInit() {
this.isLoadingObservable = this._globalLoadingIndicatorService.isLoadingObservable;
}
}
在我的HTML模板中,我绑定isLoadingObservable
:
<div *ngIf="isLoadingObservable | async">Loading...</div>
现在,当我需要一个全局加载指示符时,我会注入服务并使用方法:
export class MyComponent implements OnInit, OnDestroy {
constructor(
private _myService: MyService,
private _globalLoadingIndicatorService: GlobalLoadingIndicatorService
) { }
ngOnInit(): void {
this._globalLoadingIndicatorService.addLoadingProcess();
this._myService.getData().subscribe(
x => {
this.userGroups = x;
this.userGroup = x.length > 0 ? x[0].id : null;
this._globalLoadingIndicatorService.removeLoadingProcess();
},
error => {
alert(error);
}
);
}
在某些(并非所有)组件中,我收到运行时错误:
ExpressionChangedAfterItHasBeenCheckedError
:表达式在检查后发生了变化。之前的值:'[object Object]'
。当前值:'true'
。
我读到了这个错误,发现我在Angular-Hook生命周期中更改了一个以UI Update结尾的变量。
其中我找到了这篇文章:Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError
error
由于这篇文章,我不喜欢使用ChangeDetectorRef.detectChanges
或setTimeout
的解决方案。
如何更改全球 -Loading-Indicator来解决此问题?
我还在GitHub上找到了一个问题主题:ExpressionChangedAfterItHasBeenCheckedError
when changing a component value in afterViewInit
#14748
特别是8月4日 minuz 的解决方案:我看不出与我的代码有什么不同。为什么它适合他而不适合我?