угловые 2 модели, управляемые вложенными компонентами формы
Что я имею:
Я строю приложение ionic 2 и построил базовый угловой компонент 2, который содержит
Поле ввода
Метка для отображения заголовка ввода
Метка для отображения любых ошибок валидации
Я буду называть это моим компонентом ввода
У меня есть компонент страницы с формой на нем, и в настоящее время есть текстовые входы. 1 обычный ввод (пароль) и 1 вход, завернутый в мой компонент ввода (имя пользователя).
это релевантная часть моего компонента страницы
ngOnInit() {
this.loginForm = this.formBuilder.group({
username: ['', Validators.required],
password: ['', Validators.required]
});
}
Это шаблон компонента страницы
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<!-- My input component -->
<aw-input-text id="username" name="Username" [formInput]="loginForm.controls.username"></aw-input-text>
<!-- A standard input control -->
<ion-item [class.error]="loginForm.controls.password.errors">
<ion-label floating>Password</ion-label>
<ion-input type="text" value="" name="password" formControlName="password"></ion-input>
<p *ngIf="loginForm.controls.password.errors">This field is required!</p>
</ion-item>
<button type="submit" class="custom-button" [disabled]="!loginForm.valid" block>Login</button>
</form>
Это шаблон для моего компонента ввода
<!-- Component template -->
<form [formGroup]="formGroup">
<ion-item>
<ion-label floating>{{inputName}}</ion-label>
<ion-input type="text" formControlName="inputValue"></ion-input>
<p *ngIf="!formGroup.controls.inputValue.valid">This field is required!</p>
</ion-item>
</form>
и это входной компонент
import {Component, Input} from '@angular/core';
import {FormBuilder} from '@angular/forms';
@Component({
selector: 'aw-input-text',
templateUrl: 'build/shared/aw-input-text/aw-input-text.html'
})
export class AwInputText {
@Input('formInput')
public formInput;
@Input('name')
public inputName;
public formGroup;
constructor(private formBuilder: FormBuilder) {
}
ngOnInit() {
this.formGroup = this.formBuilder.group({
inputValue: this.formInput
});
}
}
Компонент отображается правильно.
Эта проблема:
Входные данные внутри компонента не обновляют правильное состояние формы, в которой он находится.
Когда я заполняю имя пользователя, тогда пароль формы становится действительным
Когда я заполняю пароль, то имя пользователя в форме остается недействительным
Итак, формаМожно увидеть действительное состояние входного компонента, просто изменение входного компонента не приводит к обновлению формы.
Возможное решение 1
Как описано в этой статье и Plunk
https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2
https://plnkr.co/edit/clTbNP7MHBbBbrUp20vr?p=preview
Я мог бы изменить свой компонент страницы, чтобы создать группу форм, которая содержит вложенную группу форм для каждого элемента управления формы, который я хочу использовать внутри моего компонента ввода
ngOnInit() {
this.loginForm = this.formBuilder.group({
username: this.formBuilder.group({
username: ['', Validators.required],
}),
password: ['', Validators.required],
});
}
Это решение соответствует сценарию, описанному в статье, в котором они добавляют массив элементов управления вводом, но в моем случае я считаю, что это выглядит странно
Возможное решение 2
Другое хакерское решение, которое я рассмотрел, заключается в использовании директивы @output из моего компонента ввода для запуска события на компоненте страницы, которое обновляет форму при каждом обновлении компонента ввода.
Обновление компонента ввода
this.formGroup.controls.inputValue.valueChanges.subscribe(value => {
this.formUpdated.emit({
value: value
})
});
Обновление до компонента страницы
public onUpdated(value){
this.loginForm.updateValueAndValidity();
}
и обновить шаблон компонента страницы
<aw-input-text id="username" name="Username" (updated)="onUpdated($event)" [formInput]="loginForm.controls.username"></aw-input-text>
Это дает мне желаемую функциональность, но я думаю, что немного странно иметь обработчик событий на каждой странице формы, чтобы заставить работать компонент ввода.
Вопрос
Есть ли способ заставить мой компонент обновить действительное состояние формы, в которой он находится (имея в виду, что я хотел бы повторно использовать этот компонент несколько раз в каждой форме), не прибегая к решению, описанному выше.