gpt4 book ai didi

angular - 为什么 Angular 在自定义 ControlValueAccessor 组件上调用 `registerOnChange` 之后调用 `ngOnDestroy`?

转载 作者:行者123 更新时间:2023-12-04 17:13:08 27 4
gpt4 key购买 nike

创建自定义表单元素后,我注意到当我离开托管该自定义表单元素的路由时,Angular 会调用表单元素的 ngOnDestroy 方法,然后调用表单元素的registerOnChangeregisterOnTouched 方法。我不确定为什么它会在此时调用这两个方法,但我绝对不明白为什么它会调用它们after ngOnDestroy.

我在这里创建了这个错误的最小复制:https://stackblitz.com/edit/angular-ivy-6jhgh6

这种行为对我来说是有问题的,因为在我的实际应用程序中,我正在销毁 CodeMirror 编辑器的实例并将变量引用设置为 null,但在 registerOnTouched 方法,我引用了那个变量。这会导致空引用错误。这在升级到 Angular 12 后才开始发生。

最佳答案

在调用组件的 ngOnDestroy Hook 之后调用 registerOnChangeregisterOnTouched 方法是调用 FormControlName.ngOnDestroy() 的结果

当一个 View 被销毁时,我的理解来自this function是将调用销毁 View 中的所有 onDestroy Hook 。所以,这就是为什么该 View 的表单指令也会调用它们的 onDestroy 钩子(Hook)。

这就是 FormControlName.ngOnDestroy() 上发生的事情:

// `formDirective` refers to the parent `FormGroup` directive
this.formDirective.removeControl(this);

这就是 FormGroupDirective.removeControl() 上发生的事情::

removeControl(dir: FormControlName): void {
cleanUpControl(dir.control || null, dir, /* validateControlPresenceOnChange */ false);
removeListItem(this.directives, dir);
}

最后,cleanUpControl是调用 registerOnChangeregisterOnTouched 方法的地方:

// Reverts configuration performed by the `setUpControl` control function.
// Effectively disconnects form control with a given form directive.
// This function is typically invoked when corresponding form directive is being destroyed.
export function cleanUpControl(/* ... */) {
/* ... */
const noop = () => {
if (validateControlPresenceOnChange && (typeof ngDevMode === 'undefined' || ngDevMode)) {
_noControlError(dir);
}
};

if (dir.valueAccessor) {
dir.valueAccessor.registerOnChange(noop);
dir.valueAccessor.registerOnTouched(noop);
}
/* .... */
}

因此,根据我的理解,它是清理机制的一部分。确实有点不方便,因为那些方法在view建立的时候调用,view销毁的时候也调用。我想解决方案是首先检查 null/undefined 值。

如果您想进一步探索,可以使用 debugger 关键字:

registerOnChange(fn: any): void {
debugger;
this.con.log(`registerOnChange (${this.id})`);
}

然后打开 StackBlitz 项目中的 DevTools。

关于angular - 为什么 Angular 在自定义 ControlValueAccessor 组件上调用 `registerOnChange` 之后调用 `ngOnDestroy`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69125667/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com