我有一个在实时页面中使用的组件,我一直保持分离:
@Component(...)
export class MyComponent implements AfterViewInit {
initialized = false;
constructor(private cdr: ChangeDetectorRef) {
}
ngAfterViewInit() {
this.cdr.detach();
this.initialized = true;
}
detectChanges() {
if (this.initialized) this.cdr.detectChanges();
}
methodThatUpdatesSomeState() {
this.someState = "new value";
this.detectChanges();
}
}
在模板内部,我使用了一个不纯的管道(非常类似于async
管道)isAuthorized
,它订阅了一个 observable 并调用ChangeDetectorRef
来触发更新:
@Pipe({ name: 'isAuthorized', pure: false })
export class IsAuthorizedPipe implements PipeTransform, OnDestroy {
private _subscription: Subscription;
private _authorizationKey: string = null;
private output = false;
constructor(protected loginService: LoginService, protected _ref: ChangeDetectorRef) {}
transform(value: any, authKey: string): any {
if (authKey === this._authorizationKey) return this.output;
if (this._subscription) this._subscription.unsubscribe();
this._authorizationKey = authKey;
this.output = false;
if (this._authorizationKey) {
// canExec returns an Observable<boolean>
this._subscription = this.loginService
.canExec(value, authKey)
.pipe(distinctUntilChanged())
.subscribe(isAuthorized => {
this.output = isAuthorized;
// here I should call this._ref.detectChanges(), but only when the
// component is detached
this._ref.markForCheck();
});
}
return this.output;
}
ngOnDestroy(): void {
if (this._subscription) this._subscription.unsubscribe();
}
}
像异步管道一样,这在“正常”组件和ChangeDetectionStrategy
设置为OnPush
.
但是,如果我在组件分离时尝试使用它,它将完全排除在更改检测之外,因此调用markForCheck
无效。
理想情况下,我想让管道检测到组件已分离,并调用this._ref.detectChanges()
而不是markForCheck
. 如果组件未分离,
我不想打电话,以免弄乱“正常”更改检测流程。detectChanges
有任何想法吗?