在 Angular 4.x 中对于使用 Template-Driven 表单场景,如果需要实现表单数据绑定。我们就需要引入 ngModel
指令。该指令用于基于 domain 模型,创建 FormControl
实例,并将创建的实例绑定到表单控件元素上。
ngModel 使用示例
app.component.ts
@Component({
selector: 'exe-app',
template: `
<form novalidate #f="ngForm">
Name: <input type="text" name="username" ngModel>
</form>
{{ f.value | json }}
`,
})
export class AppComponent implements OnInit { }
在 <form>
表单中使用 ngModel
时,我们需要设置一个 name
属性,以便该控件可以使用该名称在表单中进行注册。
单向绑定 – [ngModel]
app.component.ts
@Component({
selector: 'exe-app',
template: `
<form novalidate #f="ngForm">
Name: <input type="text" name="username" [ngModel]="user.username">
</form>
{{ user | json }}
`,
})
export class AppComponent implements OnInit {
user: { username: string };
ngOnInit() {
this.user = { username: 'Semlinker' };
}
}
双向绑定 – [(ngModel)]
app.component.ts (表单中应用)
@Component({
selector: 'exe-app',
template: `
<form novalidate #f="ngForm">
Name: <input type="text" name="username" [(ngModel)]="user.username">
</form>
{{ user | json }}
`,
})
export class AppComponent implements OnInit {
user: { username: string };
ngOnInit() {
this.user = { username: 'Semlinker' };
}
}
app.component.ts (单独应用)
import { Component } from '@angular/core';
@Component({
selector: 'exe-app',
template: `
<input name="username" [(ngModel)]="username">
{{username}}
`,
})
export class AppComponent {
username: string;
}
ngModelOptions – [ngModelOptions]
当你在使用 ngModel 时未设置 name 属性,如下所示:
<form novalidate #f="ngForm">
Name: <input type="text" [(ngModel)]="user.username">
</form>
当你运行时,浏览器控制台将会抛出以下异常信息:
Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
以上异常信息告诉我们,如果在表单标签中使用 ngModel,则必须设置 name 属性,或者在 ngModelOptions 中必须将表单控件定义为 “standalone”。依据上述异常信息,我们做如下调整:
<form novalidate #f="ngForm">
Name: <input type="text" [(ngModel)]="user.username"
[ngModelOptions]="{standalone: true}">
</form>
接下来我们看一下 ngModelOptions 支持的对象类型:
@Input('ngModelOptions') options: {name?: string, standalone?: boolean};
禁用控件 – disabled
<form novalidate #f="ngForm">
Name: <input type="text" name="username"
[(ngModel)]="user.username" disabled="true">
</form>
监听 ngModelChange 事件 – (ngModelChange)
app.component.ts
@Component({
selector: 'exe-app',
template: `
<form novalidate #f="ngForm">
Name: <input type="text" name="username" (ngModelChange)="userNameChange($event)"
[(ngModel)]="user.username">
</form>
{{ user | json }}
`,
})
export class AppComponent implements OnInit {
user: { username: string };
ngOnInit() {
this.user = { username: 'Semlinker' };
}
userNameChange(name: string) {
console.log(name);
}
}
获取关联的 NgModel 对象
app.component.ts
@Component({
selector: 'exe-app',
template: `
<form novalidate #f="ngForm">
Name: <input type="text" name="username" #userName="ngModel"
[(ngModel)]="user.username">
</form>
{{ userName.control | json }}
`,
})
export class AppComponent implements OnInit {
user: { username: string };
ngOnInit() {
this.user = { username: 'Semlinker' };
}
}
通过使用 userName="ngModel"
方式,我们可以获取表单控件关联的 NgModel 对象,进而获取控件当前控件的相关信息,如控件的当前的状态或控件验证信息等。
完整示例
app.component.ts
import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
selector: 'exe-app',
template: `
<form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
<input name="first" ngModel required #first="ngModel">
<input name="last" ngModel>
<button>Submit</button>
</form>
<p>First name value: {{ first.value }}</p>
<p>First name valid: {{ first.valid }}</p>
<p>Form value: {{ f.value | json }}</p>
<p>Form valid: {{ f.valid }}</p>
`,
})
export class AppComponent {
onSubmit(f: NgForm) {
console.log(f.value); // { first: '', last: '' }
console.log(f.valid); // false
}
}