表单指令
表单指令包含了一系列在表单中使用的指令,这些指令被包含在下列三个模块中:
1. FormsModule
2. ReactiveFormsModule
3. InternalFormsSharedModule
FormsModule模块
NgForm
NgForm指令是表单的控制中心,负责处理表单内的页面逻辑,为普通的表单元素扩充了许多额外的特性。所有的表单指令都需要在NgForm指令内部才能正常
import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';
@Component({
selector: 'example-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 SimpleFormComp {
onSubmit(f: NgForm) {
console.log(f.value); // { first: '', last: '' }
console.log(f.valid); // false
}
}
开发者可以不用在模板中显示使用NgForm指令,因为添加了FormsModule模块后,Angular模板在编译解析时,遇到标签会自动创建一个NgForm指令并且将其添加到该的标签上。
NgModel
NgModel指令是表单数据绑定的核心所在,是表单运用中最重要的一个指令,几乎所有的表单特性都依赖NgModel指令实现。NgModel指令实现了表单控件的数据绑定,表单的单向数据绑定使用了[ngModel],双向数据绑定使用[(ngModel)]
//单向数据绑定
<input type="text" [ngModel]="appTitle"/>
//双向数据绑定
<input type="text" [(ngModel)]="appTitle"/>
NgModelGroup
NgModelGroup 指令可以对表单输入的内容进行分组,方便我们在语义上区分不同类型的输入
<fieldset ngModelGroup="address">
<legend>Address</legend>
<div>
Street: <input type="text" [(ngModel)]="person.address.country" name="country" #country="ngModel" required />
</div>
<div>country ok : {{ country.valid }}</div>
</fieldset>
- InternalFormsSharedModule模块中包含的指令
在表单章节中已经对上述几个表单指令将结果,这里也不再赘述。
ReactiveFormsModule模块
ReactiveFormsModule模块包含:
FormControlDirective
FormControlDirective指令可以将一个已有的表单组合绑定到一个DOM元素,下面示例中,将声明的nameControl绑定给一个输入元素,当输入元素的值发生变化时,nameControl的值也发生变化,同时nameControl的值发生变化,输入元素的值也发生变化。
import {Component} from '@angular/core';
import {NgForm, FormControl} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form>
<input type="text" [formControl]="nameControl"/>
<div>{{nameControl.value}}</div>
</form>
`,
})
export class SimpleFormComp {
nameControl:FormControl=new FormControl('');
}
FormGroupDirective
FormGroupDirective可以将一个已有的表单组个绑定到一个DOM元素。
import {Component} from '@angular/core';
import {NgForm, FormControl, FormGroup} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="nameForm">
<input type="text" formControlName="name"/>
<div>{{nameForm.value|json}}</div>
</form>
`,
})
export class SimpleFormComp {
nameForm:FormGroup;
constructor(){
this.nameForm=new FormGroup({
name:new FormControl("")
})
}
}
FormControlName
FormControlName将一个已有的表单空间与一个DOM元素绑定,绑定时使用FormControlName指令为表单控件指定一个别名,这一指令作为FormGroupDirective指令的子元素使用。
<form [formGroup]="nameForm">
<input type="text" formControlName="name"/>
<div>{{nameForm.value|json}}</div>
</form>
FormGroupName
FormGroupName可以将已有的表单组合绑定到一个DOM元素上,它仅作为FormGroupDirective指令的子元素使用
import {Component} from '@angular/core';
import {NgForm, FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="myForm">
<div formGroupName="name">
<input type="text" formControlName="first"/>
<input type="text" formControlName="last"/>
</div>
</form>
`,
})
export class SimpleFormComp {
myForm:FormGroup=new FormGroup({
name:new FormGroup({
first:new FormControl('qw',Validators.required),
last:new FormControl('wq',Validators.required)
})
});
}
FormArrayName
FormArrayName指令可以将一个已有的表单数组绑定到一个DOM元素中,它仅作为FormGroupDirective指令的子元素使用。
import {Component} from '@angular/core';
import {FormArray, FormControl, FormGroup} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div formArrayName="cities">
<div *ngFor="let city of arrayCities.controls; let i=index">
<input [formControlName]="i" placeholder="City">
</div>
</div>
<button>Submit</button>
</form>
{{form.value|json}}
<button (click)="addCity()">Add City</button>
<button (click)="setPreset()">Set preset</button>
`,
})
export class SimpleFormComp {
arrayCities:FormArray=new FormArray([
new FormControl('SF'),
new FormControl('NY')
]);
form = new FormGroup({
cities: this.arrayCities
});
addCity() { this.arrayCities.push(new FormControl()); }
onSubmit() {
console.log(this.arrayCities.value);
console.log(this.form.value);
}
setPreset() { this.arrayCities.patchValue(['LA', 'MTV']); }
}
InternalFormsSharedModule
InternalFormsSharedModule模块是Angular的内部模块,FormsModule和ReactiveFormsModule模块中均引入了InternalFormsSharedModule模块,因此引入FormsModule和ReactiveFormsModule模块时,可以使用InternalFormsSharedModule模块包含的指令。FormsModule和ReactiveFormsModule模块包含的指令中包含三部分。
表单元素访问指令
- DefaultValueAccessor
- NumberValueAccessor
- CheckboxControlValueAccessor
- RadioControlValueAccessor
- SelectControlValueAccessor、selectMultipleControlValueAccessor
访问器指令是Angular表单的内部指令,在应用中无须主动使用,他们是DOM元素和表单输入空间之间的桥梁。其中ControlValueAccessor是其他访问器指令的父接口,抽象了Angular控件与DOM元素交互的公共方法。
选择框选项指令:
- NgSelectOption
- NgSelectMultipleOption
上述指令为Angular内部指令,他们动态标记选择框的选项,当选项改变时,Angular会接收到通知。
控件状态指令
- NgControlStatus
- NgControlStatus
上述指令是Angular表单的内部指令,在应用中无须主动使用,它会自动根据控件是否通过验证,是否被触摸灯状态来设置元素的css类