我有一个用 Angular 2 反应式(数据驱动)模板编写的简单登录表单。它工作完美,但是当我刷新页面并且浏览器填充电子邮件+密码(自动完成)时,我的表单的有效属性似乎是错误的。
但是当我在表单无效时按任意键或单击页面中的任意位置时,角度会更新一些状态(我猜)并且我的表单变得有效。
如何触发该状态?我怎么能说“嘿,再检查一下我的表格。”?我无法触发自己的验证脚本,因为某些验证消息是警报。如果我这样做,当用户打开此页面时,他/她将看到这些警报。
我记得,我使用触发器('input')技巧来更新 ng-model。
updateValueAndValidity()
就是您正在寻找的。该文档位于:AbstractControl。它可以强制重新计算控件的值和验证状态。
这是一个演示:
form.组件.ts
export class FormComponent implements OnInit {
myform: FormGroup;
// explicit validation of each field
emailValid: AbstractControl;
passwordValid: AbstractControl;
constructor(private fb: FormBuilder) {
this.myform = fb.group({
'email': ['', Validators.required],
'password': ['', Validators.required],
});
this.emailValid = this.myform.controls['email'];
this.passwordValid = this.myform.controls['password'];
}
ngOnInit() {
this.myform.get('email').valueChanges.subscribe(()=>forceValidAgain());
this.myform.get('password').valueChanges.subscribe(()=>forceValidAgain());
}
forceValidAgain(){
this.emailValid.updateValueAndValidity();
this.passwordValid.updateValueAndValidity();
}
}
form.component.html
<form [formGroup]="myform" (ngSubmit)="onSubmit(myform.value)">
<div class="form-group">
<label for="email">Email</label>
<input type="email"
class="form-control"
id="email"
name="email"
[formControl]="myform.controls['email']"
[ngClass]="{'is-invalid': !emailValid.valid && emailValid.touched }">
<div
class="invalid-feedback"
*ngIf="emailValid.hasError('required')">
This field is required
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password"
class="form-control"
id="password"
name="password"
[formControl]="myform.controls['password']"
[ngClass]="{'is-invalid': !passwordValid.valid && passwordValid.touched}">
<div
class="invalid-feedback"
*ngIf="passwordValid.hasError('required')">
This field is required
</div>
</div>
</form>
我建议创建一个像 onValueChanged 这样的方法(Angular2 文档中提到),将其绑定到您的表单,并在组件初始化时执行它。因此,绑定到表单更改应该以这种方式完成:
this.form.valueChanges.subscribe((data) => {
this.onValueChanged(data)
});
执行例如下面的行,如下所示:
this.onValueChanged();
此执行应该可以通过组件初始化期间的验证来解决您的问题。
我认为文档(如下)中的方法实现非常清楚。
onValueChanged(data?: any) {
if (!this.heroForm) { return; }
const form = this.heroForm;
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
我指的是文档:https://angular.io/docs/ts/latest/cookbook/form-validation.html
如果您使用 arrayForm 嵌套表单,则必须更新控件,然后更新父表单(数组项),然后更新主表单,它将起作用,例如:
control?.updateValueAndValidity();
parentForm.updateValueAndValidity();
this.mainForm.updateValueAndValidity();