ChangeDetectionStrategy.OnPush 打破 ControlValueAccessor 的禁用状态

ChangeDetectionStrategy.OnPush breaks the disabled state of a ControlValueAccessor

在我的 Angular 应用程序中,我通过实现 ControlValueAccessor 接口创建了一个自定义表单元素。

因此在我的组件中我正确地实现了该接口的所有方法,包括 setDisabledState:

/**
 * This function is called when the control status changes to or from "disabled".
 * Depending on the value, it will enable or disable the appropriate DOM element.
 *
 * @param isDisabled
 */
setDisabledState(isDisabled: boolean): void {
  this.disabled = isDisabled;
}

一切正常。

问题是当我将组件的 ChangeDetectionStrategy 设置为 OnPush

这样一来,我的组件的 enable/disable 功能就被破坏了。

可以通过手动触发变化检测来解决问题。

我们需要将 ChangeDetectorRef 注入到我们的组件中:

import {  ChangeDetectorRef } from '@angular/core';

// ...

constructor(
  private cd: ChangeDetectorRef,
) { }

然后在 enabled/disabled 状态发生变化时使用它手动触发变化检测:

setDisabledState(isDisabled: boolean): void {
  this.disabled = isDisabled;
  this.cd.markForCheck(); // this will manually trigger the change detection
}

OnPush 只有在我们谈论 parent / child 组件通信时才有意义。当 child 具有 changeDetection: ChangeDetectionStrategy.OnPush 设置并且 parent 将 object 作为输入传递给 child 时。

如果您正在创建一个具有自己状态的响应式自定义表单控件。最好避免使用 onPush。如果要使用,可以手动使用cdr.markforCheck()手动调用Change detection。