Angular 12 - TypeError: Cannot read property of null (reading 'writeValue')
我正在创建一个通用的文本输入组件,一切都工作得很好,同时服务于项目,但在构建的项目中,我得到这个错误:
TypeError:不能读空的属性(阅读writeValue)
HTML:
<div class="p-field">
<label>{{label}} <span class="p-error">{{checkRequired(ngControl.control) ? '*' : ''}}</span></label>
<input class="full-width" [type]="type" pInputText [formControl]="ngControl.control">
<small *ngIf="ngControl.control.touched && ngControl.control.errors?.required" class="p-error">{{label}} is required</small>
<small *ngIf="ngControl.control.errors?.minlength" class="p-error">
{{label}} must be at least {{ngControl.control.errors.minlength['requiredLength']}}
</small>
<small *ngIf="ngControl.control.errors?.maxlength" class="p-error">
{{label}} must be at most {{ngControl.control.errors.maxlength['requiredLength']}}
</small>
<small *ngIf="ngControl.control.errors?.email" class="p-error">
This email is not valid
</small>
<small *ngIf="ngControl.control.errors?.isMatching" class="p-error">Passwords do not match</small>
</div>
component.ts
import { Component, Input, OnInit, Self } from '@angular/core';
import {AbstractControl, ControlValueAccessor, NgControl} from '@angular/forms';
@Component({
selector: 'app-text-input',
templateUrl: './text-input.component.html',
styleUrls: ['./text-input.component.css']
})
export class TextInputComponent implements ControlValueAccessor {
@Input() label: string;
@Input() type = 'text';
constructor(@Self() public ngControl: NgControl) {
this.ngControl.valueAccessor = this;
}
checkRequired(control) {
if (control.validator) {
const validator = control.validator({} as AbstractControl);
if (validator && validator.required) {
return true;
}
}
}
writeValue(obj: any): void {
}
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
}
角信息:
Angular CLI: 12.2.6节点:14.17.3包管理器:npm 6.14.13操作系统:win32 x64角:12.2.6
在我的例子中,出现特定的错误是因为我没有在模块导入中添加特定的组件。
当提供程序设置缺失时发生错误
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi:true,
useExisting: CUSTOMER_INPUT_CLASS_HERE
}
]
在你的情况下
@Component({
selector: 'app-text-input',
templateUrl: './text-input.component.html',
styleUrls: ['./text-input.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi:true,
useExisting: TextInputComponent
}
]
})
export class TextInputComponent implements ControlValueAccessor {
...
}
可能有点晚了,但它可能会帮助这里的人:
当我将formControlName
附加到mat-radio-button
而不是mat-radio-group
时,我得到了这个错误。
当您在任何非输入元素(如<div>
)上使用formControlName
时,也会出现相同的错误。因此,请确保在输入元素上使用formControlName
属性或select
来绑定值。
这个答案可能对寻找同样错误的人有帮助。
在构造函数使用@Optional()
和做空检查:
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) this.ngControl.valueAccessor = this;
}
同时,为
等方法添加bodywriteValue(value: number): void {
this.value = value;
this.onChange(this.value);
}
onChange: (_: any) => void = (_: any) => {};
onTouched: () => void = () => {};
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
当我试图在验证逻辑的后端部分进行授权检查时,我得到了这个错误。我在formbuilder组中声明了提交按钮。当我使用style="display: none">
检查module.ts。我们需要将DropDownsMoudle导入到用户下拉列表中。
import {DropDownsModule} from "@progress/kendo-angular-dropdowns"
我建议您创建一个名为SharedModule的模块,您将在declarations数组中声明所有共享组件。在exports数组中,导出自定义文本输入组件。然后,在需要使用该组件的地方,把共享模块导入到你的app.module中。记住要删除app.module中的input声明,只导入sharedModule。还要记住在sharedModule.ts
中导入ReactiveFormsModule和FormsModule。