ChangeDetectionStrategy.OnPush 打破了 ControlValueAccessor 的禁用状态
Posted
技术标签:
【中文标题】ChangeDetectionStrategy.OnPush 打破了 ControlValueAccessor 的禁用状态【英文标题】:ChangeDetectionStrategy.OnPush breaks the disabled state of a ControlValueAccessor 【发布时间】:2019-01-28 12:52:26 【问题描述】:在我的 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
时。
这样做会破坏我的组件的启用/禁用功能。
【问题讨论】:
【参考方案1】:OnPush 只有在我们谈论父/子组件通信时才有意义。当孩子有 changeDetection: ChangeDetectionStrategy.OnPush 设置并且父母将对象作为输入传递给孩子时。
如果您正在创建具有自己状态的反应式自定义表单控件。最好避免使用 onPush。如果你想使用,你可以使用 cdr.markforCheck() 手动调用 Change detection。
【讨论】:
感谢您的建议,但就我而言,我只是想解决图书馆现有组件的问题。所以改变变化检测策略不是我的决定:github.com/valor-software/ngx-bootstrap/issues/4055【参考方案2】:可以通过手动触发变更检测来解决问题。
我们需要将ChangeDetectorRef 注入到我们的组件中:
import ChangeDetectorRef from '@angular/core';
// ...
constructor(
private cd: ChangeDetectorRef,
)
然后在启用/禁用状态更改时使用它手动触发更改检测:
setDisabledState(isDisabled: boolean): void
this.disabled = isDisabled;
this.cd.markForCheck(); // this will manually trigger the change detection
【讨论】:
以上是关于ChangeDetectionStrategy.OnPush 打破了 ControlValueAccessor 的禁用状态的主要内容,如果未能解决你的问题,请参考以下文章