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

Chrome扩展中Angular表单禁用时出现_rawValidators空引用错误

解决Angular Material Stepper中调用表单控件disable()时出现的TypeError: Cannot read properties of null (reading '_rawValidators')错误

在开发Chrome扩展时,使用Angular Material Stepper,其中一个步骤关联表单组SOQLObject,调用表单控件disable()方法时,后台错误标签页及控制台抛出以下错误:

ERROR TypeError: Cannot read properties of null (reading '_rawValidators')

移除disable()方法后错误消失,但业务需要保留禁用输入的功能。已排除表单控件命名错误、ngModel与formControl混用等常见问题,且在StackBlitz中无法复现该错误。

相关代码

HTML代码

<mat-step label="Object/Fields" [stepControl]="SOQLObject">
  <form [formGroup]="SOQLObject" class="col-3">
    <section class="object-input">
      <div formGroupName="objectStep">
        <label for="typeahead-focus">
          Select Object:
        </label>
        <input
          type="text"
          class="form-control"
          [ngbTypeahead]="search"
          (focus)="focus$.next($any($event).target.value)"
          (click)="click$.next($any($event).target.value)"
          #objectSelect="ngbTypeahead"
          formControlName="objectInput"
        />
      </div>
      <!-- Empty field -->
      <div
        style="align-self: end; margin-top: 15px"
        *ngIf="ObjectInputCT.dirty"
      >
        <button
          mat-icon-button
          (click)="resetObjectSelect()"
          title="Clear the Selected Object"
        >
          <mat-icon>arrow_back</mat-icon>
        </button>
      </div>
    </section>
  </form>
</mat-step>

TypeScript代码

SOQLObject = this._formBuilder.group({
  objectStep: this._formBuilder.group({
    objectInput: ["", Validators.required],
  }),
});

ObjectInputCT = this.SOQLObject.controls["objectStep"].controls["objectInput"];

ngOnInit(): void {
  this.ObjectInputCT.valueChanges.subscribe((val) => {
    if (!this.OBJECTSLIST.includes(val as string)) {
      this.ObjectInputCT.setErrors({ invalid: true });
    } else {
      this.ObjectInputCT.setErrors(null);
      this.ObjectInputCT.disable({
        onlySelf: true,
        emitEvent: false,
      });
      this.objectSelectChild.dismissPopup();
    }
    if (val == "" || val == " ") {
      this.ObjectInputCT.markAsPristine();
    }
  });
}

解决方案

这个错误多是Chrome扩展的沙箱环境、Angular表单状态变更周期与Stepper步骤控制逻辑冲突导致的,可尝试以下几种方案:

  • 方案1:延迟执行禁用操作
    把disable()放在setTimeout中,让Angular完成当前表单状态变更周期后再执行,避免状态冲突:

    else {
      this.ObjectInputCT.setErrors(null);
      setTimeout(() => {
        this.ObjectInputCT.disable({
          onlySelf: true,
          emitEvent: false,
        });
      }, 0);
      this.objectSelectChild.dismissPopup();
    }
    
  • 方案2:通过表单组定位控件执行禁用
    改用表单组的get()方法定位控件后执行禁用,避免直接引用控件可能带来的状态异常:

    else {
      this.ObjectInputCT.setErrors(null);
      this.SOQLObject.get('objectStep.objectInput')?.disable({
        onlySelf: true,
        emitEvent: false,
      });
      this.objectSelectChild.dismissPopup();
    }
    
  • 方案3:用readonly替代控件禁用
    如果上述方案仍有问题,可暂时用HTML的readonly属性实现输入不可编辑的效果,规避表单控件状态变更带来的异常:
    在input标签中添加条件性readonly:

    <input
      type="text"
      class="form-control"
      [ngbTypeahead]="search"
      (focus)="focus$.next($any($event).target.value)"
      (click)="click$.next($any($event).target.value)"
      #objectSelect="ngbTypeahead"
      formControlName="objectInput"
      [readonly]="ObjectInputCT.valid && OBJECTSLIST.includes(ObjectInputCT.value as string)"
    />
    

    同时移除TS代码中的disable()调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:11:11