#angular #angular-material #angular-reactive-forms #code-reuse #controlvalueaccessor
#angular #angular-материал #angular-reactive-forms #повторное использование кода #controlvalueaccessor
Вопрос:
Я следую этому руководству ControlContainer
по созданию многоразовых форм, успешно создал группу многоразовых форм, но когда я попытался создать многоразовый элемент формы с matInput
помощью, столкнулся с No value accessor
ошибкой. Вот my-form-field.ts
файл:
import { Component, Input, OnInit } from '@angular/core';
import {
ControlContainer,
FormBuilder, FormControl,
FormGroup,
FormGroupDirective,
} from '@angular/forms';
@Component({
selector: 'my-form-field',
template: `
<mat-form-field>
<mat-label>{{label}}</mat-label>
<input matInput [formControlName]="formControlName">
</mat-form-field>
`,
viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
})
export class MyFormFieldComponent implements OnInit {
@Input() formControlName: string;
@Input() label: string;
formGroup: FormGroup;
constructor(private ctrlContainer: FormGroupDirective, private formBuilder: FormBuilder) {
}
ngOnInit(): void {
this.formGroup = this.ctrlContainer.form;
const control = new FormControl('');
this.formGroup.addControl(this.formControlName, control);
}
}
И вот как я это использую:
<form [formGroup]='formGroup'>
<my-form-field label='Test' formControlName='name'></my-form-field>
</form>
Воссоздал пример здесь:
https://stackblitz.com/edit/angular-9-material-reusable-matinput?file=src/app/my-form-field.ts
Мой подход может быть неправильным, поэтому предложение для повторно используемого компонента формы matInput тоже в порядке.
Комментарии:
1. Для повторно используемого элемента управления формой ваш компонент должен реализовать ControlValueAccessor..
2. @MikeOne, нет, это не обязательно. Существует другой подход: опция, которая использует Envil (с использованием
{ provide: ControlContainer, useExisting: FormGroupDirective }
или передает непосредственно FormControl.3. Хорошо, спасибо, что дали мне знать. Я всегда использую ControlValueAccessor, не знал, что есть другой способ.
Ответ №1:
Вы используете в качестве имени @Input
formControlName
, это делает Angular запутанным, используйте другое имя, например controlName
<my-form-field label='Test' controlName='name'></my-form-field>
И во вводе
@Input('controlName') formControlName: string;