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)。它可能不漂亮,但通常工作正常。是的,我知道它工作正常,因为它是异步的,但有些奇怪