0

我有一个在实时页面中使用的组件,我一直保持分离:

@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

有任何想法吗?

4

0 回答 0