Angular 12 - TypeError: невозможно прочитать свойства null (чтение 'writeValue')
Angular 12 - TypeError: невозможно прочитать свойства null (чтение 'writeValue')
Я создаю общий компонент ввода текста, все работает хорошо при обслуживании проекта, но во встроенном проекте я получаю эту ошибку:
TypeError: невозможно прочитать свойства null (чтение '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 x64Angular: 12.2.6
9 ответов
В моем случае появлялась конкретная ошибка, потому что я не добавил конкретный компонент в импорт модуля.
Ошибка возникает, когда отсутствует настройка провайдера
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
атрибут над входными элементами илиselect
связать значения.
Этот ответ может быть полезен для тех, кто ищет ту же ошибку.
Проверьте модуль.ts. Нам нужно импортировать DropDownsMoudle в выпадающие списки пользователей.
импортировать {DropDownsModule} из "@progress/kendo-angular-dropdowns";
Я бы посоветовал вам создать модуль SharedModule, где вы объявите все ваши общие компоненты в массиве объявлений. в вашем массиве экспорта экспортируйте пользовательский компонент ввода текста. А затем, когда вам нужно использовать компонент, импортируйте общий модуль в свой app.module. Не забудьте удалить объявление ввода в app.module и импортировать только общий модуль. Также не забудьте импортировать ReactiveFormsModule и FormsModule в ваш sharedModule.ts.
Я получил эту ошибку, когда попытался выполнить проверку авторизации в бэкэнд-части логики проверки. Я объявил кнопку отправки в группе построителя форм. Когда я использовал ввод со стилем = "display: none", все было в порядке.
Потратив на это один час, вы не можете установить @Input() formControl и ожидать, что он будет работать, передача элемента управления в компонент должна осуществляться не через зарезервированное ключевое слово [formControl], а через какое-то другое имя переменной.
В конструкторе используйте
@Optional()
и выполните нулевую проверку:
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) this.ngControl.valueAccessor = this;
}
Кроме того, добавьте тело в такие методы, как
writeValue(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;
}