在这个方法里,我们使用theForm.invalid就可以获得这个表单是否验证成功的状态,也可以用'theForm.value'获得所有的表单数据。在这里,我们把表单数据打印到控制台来检查数据。至于如何从这个表单引用中获取控件数据和状态,会在接下来再讲。
使用ngModel绑定数据
接下来,我们需要绑定数据。假设我们的业务是打开这个页面的时候获取用户数据,然后显示到页面表单上。我们在组件的构造方法中创建一个模拟的用户数据:
export class TemplateFormsComponent { user: any; constructor() { this.user = { name: '张三', mobile: 13800138001, city: '北京', street: '朝阳望京...' }; } }
然后在模板中将这个组件中的数据绑定到模板页面上:
<input type="text" [(ngModel)]="user.name"> <input type="text" [ngModel]="user.mobile"> <input type="text" [ngModel]="user.city"> <input type="text" [ngModel]="user.street"> <!-- 其他的输入框都类似 -->
在这里,我们使用[(ngModel)]="user.name",这是双向绑定的方式,这样,当我们修改页面上的数据的时候,在组件中也能获得更新后的数据;同时,如果在组件中更新了数据,在页面上也能更新。
为了演示这个双向绑定跟单向绑定的区别,我们只对姓名使用双向绑定,对其他的都是用单向绑定,也就是[ngModel]="user.mobile"。使用[]的单向绑定是从模板到组件的绑定,也就是页面中的输入的数据改变,组件中的数据也会改变。但是组件中的数据更新不会引起页面上该数据的更新。
使用单向绑定可以减少数据的更新检查,从来可以提高性能。
如果不需要数据的初始化,我们其实可以只用ngModel,例如:
<input type="text" ngModel>
这样,我们在组件中创建的用户数据就无法显示到页面上,但是,他还是能够将页面上输入的数据绑定到组件中的数据上。
在Angular2中,使用ngModel结合name属性来创建一个表单控件FormControls。例如上面的<input ngModel>就对应一个userForm里面的控件city。由于我们在提交方法里面将这个userForm作为参数传到方法里,我们可以在方法里面获得所有的表单控件theForm.controls,它是一个Map类型的对象,key是所有的表单元素的name,值就是一个FormControl对象,里面保存着数据、和验证结果、是否修改等状态。也正是因为这些FormControls,我们才能够使用theForm.value的方式获取表单里的数据。当我们点击保存按钮的时候,就能在日志里面看到表单的数据:
{ name: "张三", mobile: 13800138001, city: "北京", street: "朝阳望京..." }
使用ngModelGroup分组显示
一般情况下,我们的model数据有可能是嵌套的,比如对于用户信息来说,城市和街道可能在一个地址对象address里,例如:
{ name: "张三", mobile: 13800138001, address: { city: "北京", street: "朝阳望京..." } }
对于这样的数据,我们就可以使用ngModelGroup来分组。模板就是这样:
<form #userForm="ngForm" (ngSubmit)="logForm(userForm)"> <label>姓名:</label> <input type="text" [(ngModel)]="user.name"> <label>电话:</label> <input type="text" [ngModel]="user.mobile"> <fieldset ngModelGroup="address"> <label>城市:</label> <input type="text" [ngModel]="user.address.city"> <label>街道:</label> <input type="text" [ngModel]="user.address.street"> <button type="submit">保存</button> </fieldset> </form>
这样我们就把地址信息都封装到一个address对象里面。注意我们绑定的数据的结构也发生改变,这样,我们也需要修改我们的组件里面的用户数据:
export class TemplateFormsComponent { user: any; constructor() { this.user = { name: '张三', mobile: 13800138001, address: { city: '北京', street: '朝阳望京...' } }; } }
至此,我们的表单的基本功能就算完成了。我们在面板中创建了表单,在组件中初始化了用户数据,并显示到页面上,在页面上用ngModel,将页面上的数据更改绑定到组件上。同时,使用name属性,使得表单里面的所有数据都成为FormControl对象。在提交所调用的方法里,获得了表单的验证状态和数据。
表单控件的验证和状态
下一步,我们来添加数据验证,Angular2为我们提供了几种最基本的验证:
required:表明该数据是必须的。
minlength:设置该字段的长度的最小值,即使输入的是数字,也按照字符串来判断长度。
maxlength:设置该字段的长度的最大值。
pattern:使用正则表达式验证
在使用Angular的验证之前,我们首先需要关闭浏览器默认的验证,不然,如果某一个输入不合法,提交按钮就无法提交。我们在form里添加novalidate:
<form #userForm="ngForm" (ngSubmit)="logForm(userForm)" novalidate>