FormControl 与FormGroup
先了解一下表单中的两个重要的类FormControl与FormGroup
FormControl:代表了表单中的input,它是Angular表单的最小单元。FormControl包含了表单input域的值、状态(校验、变化与错误)
FormGroup: 在很多时候,一个表单会有很多输入项,我们需要有一个办法来管理这么多的输入项,而引入FormGroup的目的就是为了此,它用来管理FormControl的集合。
let personInfo = new FormGroup({
name = new FormControl("li ming");
age = new FormControl("20");
zip = new FormControl("42300");
})
FormControl与FormGroup都继承于AbstractControl
模板驱动表单(Template-driven Forms)
为了使用模板驱动表单,我们需要在NgModel中引入FormsModule
创建表单组件
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-demo-form-person',
templateUrl: './demo-form-person.component.html',
demo-form-person.component.html
<form #f="ngForm" (ngSubmit)="onSubmit(f.value)" class="ui form>
<div class="field">
Forms in Angular
<label for="nameInput">UserName</label>
<input type="text" id="nameInput" placeholder="UserName" name="userName" ngModel>
</div>
<button type="submit" class="ui button">Submit</button>
</form>
当我们引入了FormsModule后,上面模板中的<form>标签就不是普通的html中的<form>标签,它是由
NgForm产生的。看一下NgForm指令的注解部分
@Directive({
selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',
providers: [formDirectiveProvider],
host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
outputs: ['ngSubmit'],
exportAs: 'ngForm'
})
NgForm指令生成的两个最主要的部分是
2、 一个(ngSubmit)的输出
<form #f="ngForm" (ngSubmit)="onSubmit(f.value)"
上面代码中,f是ngFrom变量的一个别名,因此f.value就是表单所有输入项的值。
<input type="text" id="nameInput" placeholder="UserName" name="userName" ngModel>
这里值得注意是ngModel,
NgModel指令的注解部分
@Directive({
selector: '[ngModel]:not([formControlName]):not([formControl])',
providers: [formControlBinding],
exportAs: 'ngModel'
})
这里ngModel没有设置属性,它是一个单向绑定,同时,自动创建了一个FormControl,名字叫userName,并且把这个名叫userName的对象加到FormGroup中,也就是ngForm对象中,这些都是自动完成的。
响应式表单(Reactive Forms)
相对于模板驱动的表单,FormControl与FormGroup都是自动生成的,而响应式表单则需要我们自己来处理
为了使用响应式表单,我们需要在NgModel中引入ReactiveFormsModule
创建表单组件
import { Component, OnInit } from '@angular/core'; import {
FormBuilder,
FormGroup
} from '@angular/forms';
@Component({
selector: 'app-demo-form-person-with-builder',
templateUrl: './demo-form-person-with-builder.component.html',
styles: []
})
export class DemoFormPersonWithBuilderComponent implements OnInit {
myForm: FormGroup;
constructor(fb: FormBuilder) {
this.myForm = fb.group({
'userName': ['li ming']
});
}
ngOnInit() {
}
onSubmit(value: string): void {
console.log('you submitted value: ', value);
}
}
demo-form-person-with-builder.component.html
<form [formGroup]="myForm">
<div class="field">
<label for="nameInput">Name</label>
<input type="text"
id="nameInput"
placeholder="Name"
[formControl]="myForm.controls['userName']">
</div>
<button type="submit" class="ui button">Submit</button>
</form>
这里<form>标签中有一个formGroup属性,那么这个<form>标签就不是NgForm指令产生的,看一下NgForm指令的注解
@Directive({
selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',
providers: [formDirectiveProvider],
host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
outputs: ['ngSubmit'],
exportAs: 'ngForm'
})
其中
form:not([ngNoForm]):not([formGroup])
说明当标签中有ngNoForm或formGroup属性时,则<form>不是由NgForm指令产生,只是普通的标签。这样的话<form [formGroup]="myForm"> 中formGroup就是由FormGroupDirective 指令产生的,这个指令生成了一个FormGroup对象,与组件类中的myForm绑定。而
<input type="text"
id="nameInput"
placeholder="Name"
[formControl]="myForm.controls['userName']">
的formControl则是
FormControlDirective指令产生的,它与组件类myForm.controls[`userName`]绑定。