【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
在angular中,提供了两种创建表单的方式:
- 模板驱动型表单(Template Driven Forms)
- 响应式表单(Reactive Forms)
在模板驱动型表单中,我们直接通过 ngModel 指令在组件模板中创建 control 和绑定数据,不用创建控件、表单对象或编写代码来处理组件类和模板之间的数据交流;并且,我们不会把表单验证写在组件类中。
在响应式表单中,我们在组件类中创建表单对象,并将其绑定到模板中的响应式表单控件中。所有的表单控件和数据验证都写在组件类中;表单验证和表单状态变化是异步的,我们可以在组件类写代码中观察到这一点。响应式表单通常用于数据模型确定的情形。
那么这两种创建表单的方式主要区别在哪里呢?
在响应式表单中,我们不需要用到ngModel,required等指令,我们在组件类中创建所有的控件和验证器。它很容易测试和维护。接下来,我将通过FormControl/FormGroup/FormBuilder/FormArray和添加一些表单验证功能来创建一个响应式表单。
step1: 添加响应式表单模块:Reactive Forms Module
import {ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
step2: 在组件中引入要求的类
我们需要先在组件类中引入 FormGroup, FormControl, FormArray类,这些都是帮助我们创建响应式表单的神兵利器。
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Reactive Forms Demo';
}
step3: 引用 FormControl 类
FormControl类对应一个单独的表单控件,跟踪它的值和有效性。当我们创建表单时,我们会创建一个FormControl的对象。如下:我们在组件类中创建了一个FormControl对象;
export class AppComponent {
email = new FormControl('');
}
在模板中,我们通过属性绑定将email表单控件绑定到input元素上。
<input [formControl]='email' type="text" placeholder="Enter Email"/>
{{email.value | json}}
step4: 使用 FormGroup 类
FormGroup是多个FormControl的集合,提供了一个追踪一组表单控件的值或是验证的API。它作为表单视图层的最高级,我们可以将FormGroup作为一个单独的对象,然后每个form control都看作是它的一个属性。创建一个FormGroup,如下:
loginForm = new FormGroup({
email: new FormControl(' '),
password: new FormControl(' ')
})
在这里我们创建了一个登陆表单,它有两个表单控件:email和password。对应的视图为:
<form [formGroup]='loginForm' novalidate class="form">
<input formControlName='email' type="text" class="form-control"
placeholder="Enter Email" />
<input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
</form>
{{loginForm.value | json}}
{{loginForm.status | json }}
这里,我们采用了属性绑定将formcontrolName指令和组件类中的formControl绑定起来。如果你曾经用过模板驱动型表单,会发现这没有ngModel或是name绑定到元素上。我们还可以直接通过值和状态属性来查看表单的值和状态。
step5: 提交表单
如果要提交表单,我们需要增加一个提交按纽,并且绑定提交处理函数;如下:
<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
<button class="btn btn-default">Login</button>
</form>
在组件类中,添加表单提交处理函数loginUser():
export class AppComponent implements OnInit {
loginForm: FormGroup;
ngOnInit() {
this.loginForm = new FormGroup({
email: new FormControl(null, Validators.required),
password: new FormControl()
});
}
loginUser() {
console.log(this.loginForm.status);
console.log(this.loginForm.value);
}
}
step6: 添加表单验证
要添加表单验证,需先引入angular/forms中的Validators,如下:
ngOnInit() {
this.loginForm = new FormGroup({
email: new FormControl(null, Validators.required),
password: new FormControl(null, [Validators.required, Validators.maxLength(8)])
});
}
在模板中,我们通过FormGroup发现某个control的错误,在下面,我们检查表单验证结果并且用隐藏的div显示错误。如下:
<div class="container">
<br />
<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<div class="alert alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
Email is required
</div>
<input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
<div class="alert alert-danger" *ngIf=" !loginForm.get('password').valid && loginForm.get('email').touched">
Password is required and should less than 10 characters
</div>
<button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
</form>
</div>
step7: 使用 FormBuilder
FormBuilder 用来简化FormGroup和FormControl之间的语法。当表单特别长的时候,这个类尤其有效。注入进组件中,如下:
constructor(private fb : FormBuilder){}
用它创建响应式表单如下:
this.loginForm = this.fb.group({
email: [null, [Validators.required, Validators.minLength(4)]],
password: [null, [Validators.required, Validators.maxLength(8)]]
})
组件类中的所有代码如下:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
loginForm: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.loginForm = this.fb.group({
email: [null, [Validators.required, Validators.minLength(4)]],
password: [null, [Validators.required, Validators.maxLength(8)]]
})
}
loginUser() {
console.log(this.loginForm.status);
console.log(this.loginForm.value);
}
}
总结
创建响应式表单主要用到FormControl/FormGroup/FormBuilder/FormArray这几类,同时需要先引入响应式表单模块:ReactiveFormsModule。上面几个类之间的关系为:
参考:https://dzone.com/articles/how-to-create-reactive-forms-in-angular
来源:oschina
链接:https://my.oschina.net/u/2669765/blog/1845880