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
相关产品推荐
相关产品推荐

