Angular 角度变化检测表达式changedafterithasbeenCheckedError与异步管道
我有一个与拦截器一起工作的加载程序组件:Angular 角度变化检测表达式changedafterithasbeenCheckedError与异步管道,angular,Angular,我有一个与拦截器一起工作的加载程序组件: import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { finalize } from 'rxjs/operators'; import { Loade
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { LoaderService } from '../services/loader.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
private totalRequests = 0;
constructor(private loaderService: LoaderService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.totalRequests++;
this.loaderService.setLoading(true);
return next.handle(req).pipe(
finalize(() => {
this.totalRequests--;
if (this.totalRequests === 0) {
this.loaderService.setLoading(false);
}
})
);
}
}
装载机组件:
import { Component } from '@angular/core';
import { LoaderService } from '../../services/loader.service';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['loader.component.css'],
})
export class LoaderComponent {
isLoading = this.loaderService.isLoading;
constructor(private loaderService: LoaderService) {}
}
<div class="overlay" *ngIf="isLoading | async">
<div class="lds-hourglass"></div>
</div>
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { LoaderService } from '../../services/loader.service';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['loader.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoaderComponent implements OnInit, OnDestroy {
isLoading = false;
private subs: Subscription[] = [];
constructor(private loaderService: LoaderService, private changeDetectorRef: ChangeDetectorRef) {}
ngOnInit() {
const sub = this.loaderService.isLoading.subscribe((res) => {
this.isLoading = res;
this.changeDetectorRef.detectChanges();
});
this.subs.push(sub);
}
ngOnDestroy() {
this.subs.forEach((sub) => sub.unsubscribe());
}
}
加载器服务:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class LoaderService {
private _isLoading = new BehaviorSubject<boolean>(false);
isLoading = this._isLoading.asObservable();
setLoading(isLoading: boolean) {
this._isLoading.next(isLoading);
}
}
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class LoaderService {
isLoading = new BehaviorSubject<boolean>(false);
setLoading(isLoading: boolean) {
this.isLoading.next(isLoading);
}
}
从'@angular/core'导入{Injectable};
从“rxjs”导入{BehaviorSubject};
@注射的({
providedIn:'根',
})
导出类装入器服务{
isLoading=新行为主体(false);
设置加载(isLoading:布尔值){
this.isLoading.next(isLoading);
}
}
它之所以有效,是因为使用OnPush策略,我们说的是在需要显式使用this.changeDetectorRef.detectChanges()时,将检测周期更改为渲染代码>
另一方面,我们需要使用此解决方案在卸载组件时手动处理订阅(这就是ngondestry
)一个“简单”的修复方法可能是包装此组件;在setTimeout中(时间为0)。它可能不漂亮,但通常工作正常。是的,我知道它工作正常,因为它是异步的,但有些奇怪