请问:Angular 模版驱动表单,在组件类中通过 @ViewChild 注入的表单模型(NgForm)对象为什么会变化?
最近在 angular.io 上看 Angular Form 部分的文档,看到 Template-driven Forms 章节中的一段示例代码,不太明白:
import { Component, AfterViewChecked, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Hero } from '../shared/hero';
@Component({
selector: 'hero-form-template2',
templateUrl: './hero-form-template2.component.html'
})
export class HeroFormTemplate2Component implements AfterViewChecked {
powers = ['Really Smart', 'Super Flexible', 'Weather Changer'];
hero = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What');
submitted = false;
onSubmit() {
this.submitted = true;
}
addHero() {
this.hero = new Hero(42, '', '');
}
heroForm: NgForm;
@ViewChild('heroForm') currentForm: NgForm;
ngAfterViewChecked() {
this.formChanged();
}
formChanged() {
if (this.currentForm === this.heroForm) { return; }
this.heroForm = this.currentForm;
if (this.heroForm) {
this.heroForm.valueChanges
.subscribe(data => this.onValueChanged(data));
}
}
onValueChanged(data?: any) {
if (!this.heroForm) { return; }
const form = this.heroForm.form;
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] + ' ';
}
}
}
}
formErrors = {
'name': '',
'power': ''
};
validationMessages = {
'name': {
'required': 'Name is required.',
'minlength': 'Name must be at least 4 characters long.',
'maxlength': 'Name cannot be more than 24 characters long.',
'forbiddenName': 'Someone named "Bob" cannot be a hero.'
},
'power': {
'required': 'Power is required.'
}
};
}
其中这一段:
heroForm: NgForm;
@ViewChild('heroForm') currentForm: NgForm;
ngAfterViewChecked() {
this.formChanged();
}
formChanged() {
if (this.currentForm === this.heroForm) { return; }
this.heroForm = this.currentForm;
if (this.heroForm) {
this.heroForm.valueChanges
.subscribe(data => this.onValueChanged(data));
}
}
向大家请教一下:
currentForm 这个对象引用为什么会变化?
为什么要在 ngAfterViewChecked 方法中判断通过 @ViewChild('heroForm') 注入的表单模型对象 currentForm 是否发生了变化?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先这是一种很不值得提倡的奇淫技巧,看上面的代码像是为了收集错误到固定的对象当中,没有看到HTML模板,我想只是为了单纯方便而已吧。
其次为什么说是不提倡呢?Angular本身提供模板驱动表单外,还包括模型驱动表单,居然在类中已经有构建一堆错误消息了,那还不如直接用模型驱动表单更为实在。当然这也是Angular推荐的,原因是表单易可测试性也是非常重要的。
最后,回答你的两个问题。
currentForm
表示表单对象,虽然在ngAfterViewChecked
中每一次子组合的变更都会执行一次,但实则只会执行一次,因为:我想如果把这一段代码放进
ngOnInit
也是可以的。对于this.heroForm.valueChanges
而言,只要表单对象存在的情况下订阅valueChanges
不管放在哪都可以。以上!
表单模版:
验证了一下,之所以使用
ngAfterViewChecked
,是为了应对*ngIf="active"
,所以需要做以下判断:感谢 @cipchk 的回答。
想请教一下,开发一般的简单表单,是否首选使用模版驱动的表单方式?感觉会要清晰很多。