【发布时间】:2017-01-30 11:53:19
【问题描述】:
我有什么:
我正在构建一个 ionic 2 应用程序并构建了一个基本的 angular 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],
});
}
这个解决方案适合文章中他们添加输入控件数组的场景,但在我的情况下,我认为这感觉很hacky
可能的解决方案 2
我考虑过的另一个 hacky 解决方案是使用输入组件中的 @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>
这确实为我提供了所需的功能,但我认为在每个表单页面上都有一个事件处理程序以使输入组件正常工作似乎也有点笨拙。
问题
有没有办法让我的组件更新它所在表单的有效状态(请记住,我想在每个表单中多次重复使用此组件)而不求助于上述解决方案.
【问题讨论】:
标签: javascript forms angular angular2-forms angular2-components