#angular
#угловой
Вопрос:
Я только что узнал, что существует несколько способов реализации двусторонней привязки в пользовательском компоненте. Чего я не могу понять, так это разницы между ними. Когда я говорю, я предпочитаю использовать компонент, который использует синтаксис банана в коробке (с @input()
и @Output()
для модели), чтобы реализовать двустороннюю привязку, подобную этому компоненту
@Component({ selector: 'app-first-component', template: ` lt;pgt;input model value: {{ inputModel }}lt;/pgt; lt;button (click)="clickHandler()"gt;Clearlt;/buttongt; ` }) export class FirstComponentComponent { @Input() inputModel: string; @Output() inputModelChange = new EventEmitterlt;stringgt; (); clickHandler(): void { this.inputModel = ''; this.inputModelChange.emit(this.inputModel); } }
и тот, который реализует ControlValuAccessor
вот так
@Component({ selector: 'app-second-component', template: ` lt;pgt;input model value: {{ inputModel }}lt;/pgt; lt;button (click)="clickHandler()"gt;Clearlt;/buttongt; `, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() =gt; SecondComponentComponent), multi: true }] }) export class SecondComponentComponent implements ControlValueAccessor { private inputModel: string; private onChanged: (value: string) =gt; void = () =gt; {}; clickHandler(): void { this.inputModel = ''; this.onChanged(this.inputModel); } registerOnChange(fn: any): void { this.onChanged = fn; } writeValue(value: string) { this.inputModel = value; this.onChanged(this.inputModel); } registerOnTouched(): void {/* ignored */} }
I они используются в родительском компоненте, подобном этому
lt;app-first-component [(inputModel)]="value"gt; lt;/app-first-componentgt; lt;app-second-component [(ngModel)]="value"gt; lt;/app-second-componentgt;
Как вы можете видеть, они используются одинаково и выполняют одну и ту же работу. Если да, то почему это так ControlValueAccessor
? Могу ли я что-нибудь сделать со вторым компонентом, что невозможно с первым?
Комментарии:
1.
ControlValueAccessor
используется специально для пользовательских элементов управления угловой формой2. Я думаю, что единственная разница в том, что
ControlValueAccessor
интерфейс также позволяет связыватьFormControl
s, но другой синтаксис этого не делает, верно?
Ответ №1:
Процессор ControlValueAccessor (или компонент, реализующий этот интерфейс) используется Angular в качестве моста между собственным элементом управления формой (например, ввод, текстовое поле, переключатель и т. Д.) И угловым представлением «FormControl»( ссылка в GitHub: https://github.com/angular/angular/blob/b5ab7aff433a67cddaa55e621d17b1a1b07b57c2/packages/forms/src/directives/reactive_directives/form_control_directive.ts).
Реализуя интерфейс ControlValueAccessor, вы обеспечиваете, чтобы Angulars FormControl получал уведомления при обновлении собственного элемента формы и наоборот (при программном внесении изменений в FormControl обновляется собственный пользовательский интерфейс).
Angular включает в себя процессоры управления значениями для всех известных элементов HTML-формы. Но когда вы пытаетесь создать свой собственный элемент управления формой, который не построен из собственных элементов (или вы хотите обернуть какой-то пользовательский интерфейс от третьей стороны), тогда ваш компонент должен реализовать интерфейс ControlValueAccessors, чтобы сделать ваш пользовательский элемент управления формой пользовательского интерфейса управляемым с помощью угловых форм.
[ngModel] используется в формах, управляемых шаблонами, для создания двусторонней привязки данных (пожалуйста, обратите внимание, что она помечена как устаревшая, начиная с Angular V6 (см. Ссылку выше). Таким образом, весь замысел, стоящий за этими двумя вещами, отличается. Насколько я понимаю, [ngModel] работает, потому что рабочий механизм ControlValueAccessors уже существует.