You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Angular在自定义ControlValueAccessor组件ngOnDestroy后调用registerOnChange

Angular 12+ 自定义表单控件销毁后触发registerOnXX方法问题说明

根因

该行为是Angular 12版本对表单模块的优化更新引入的官方设计:当承载自定义表单控件的路由跳转、组件销毁时,Angular表单系统会先触发自定义组件的ngOnDestroy生命周期,再调用registerOnChange、registerOnTouched传入空函数覆盖原有回调,用于清理内存、避免回调残留导致的内存泄漏。

可行解决方案

你可以根据业务场景选择以下任意一种方案解决空引用报错:

  • 方案1:给回调逻辑增加空值防御判断
    在registerOnChange、registerOnTouched的实现逻辑中,访问CodeMirror实例前先判断实例是否存在,不存在直接终止执行,示例代码如下:
    registerOnTouched(fn: () => void): void {
      this.onTouched = () => {
        // 增加空值判断
        if (!this.codeMirrorInstance) return;
        fn();
      };
    }
    
  • 方案2:调整ngOnDestroy的执行顺序
    销毁CodeMirror实例前,先把自定义控件的onChange、onTouched回调置为空函数,再执行实例销毁逻辑:
    ngOnDestroy(): void {
      // 先清空回调,避免后续被调用时报错
      this.onChange = () => {};
      this.onTouched = () => {};
      // 再销毁编辑器实例
      this.codeMirrorInstance?.destroy();
      this.codeMirrorInstance = null;
    }
    
  • 方案3:全量使用可选链访问编辑器实例
    所有用到CodeMirror实例的代码位置统一使用可选链操作符?.,即使实例为null也不会抛出空引用错误:
    // 示例:所有访问实例的位置都加可选链
    this.codeMirrorInstance?.setValue('');
    

内容的提问来源于stack exchange,提问作者Trevor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:21:04