Angular 4.x Reactive Forms
Angular 4.x 中有两种表单:
Template-Driven Forms (模板驱动表单) ,我们之前的文章已经介绍过了,了解详细信息,请查看 - Angular 4.x Template-Driven Forms 。 Contents
Form base and interfaceForm base<form novalidate> <label> <span>Full name</span> <input type="text" name="name" placeholder="Your full name"> </label> <div> <label> <span>Email address</span> <input type="email" name="email" placeholder="Your email address"> </label> <label> <span>Confirm address</span> <input type="email" name="confirm" placeholder="Confirm your email address"> </label> </div> <button type="submit">Sign up</button> </form> 接下来我们要实现的功能如下:
User interface// signup.interface.ts export interface User { name: string; account: { email: string; confirm: string; } } ngModule and reactive forms在我们继续深入介绍 reactive forms 表单前,我们必须在 import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ ...,ReactiveFormsModule ],declarations: [...],bootstrap: [...] }) export class AppModule {}
Reactive approach我们将基于上面的定义的基础表单,创建 signup-form.component.ts import { Component } from '@angular/core'; @Component({ selector: 'signup-form',template: ` <form novalidate>...</form> ` }) export class SignupFormComponent { constructor() {} } 这是一个基础的组件,在我们实现上述功能前,我们需要先介绍 FormControl and FormGroup我们先来介绍一下 FormControl 和 FormGroup 的概念:
使用示例: ngOnInit() { this.myControl = new FormControl('Semlinker'); }
使用示例: ngOnInit() { this.myGroup = new FormGroup({ name: new FormControl('Semlinker'),location: new FormControl('China,CN') }); } 现在我们已经创建了 <form novalidate [formGroup]="myGroup"> Name: <input type="text" formControlName="name"> Location: <input type="text" formControlName="location"> </form>
上面示例中,我们必须使用 FormGroup -> 'myGroup' FormControl -> 'name' FormControl -> 'location' Implementing our FormGroup modelsignup.interface.ts export interface User { name: string; account: { email: string; confirm: string; } } 与之对应的表单结构如下: FormGroup -> 'user' FormControl -> 'name' FormGroup -> 'account' FormControl -> 'email' FormControl -> 'confirm' 是的,我们可以创建嵌套的 FormGroup 集合!让我们更新一下组件 (不包含初始数据): import { Component,OnInit } from '@angular/core'; import { FormControl,FormGroup } from '@angular/forms'; @Component({...}) export class SignupFormComponent implements OnInit { user: FormGroup; ngOnInit() { this.user = new FormGroup({ name: new FormControl(''),account: new FormGroup({ email: new FormControl(''),confirm: new FormControl('') }) }); } } 如果我们想要设置初始数据,我们可以按照上述示例进行设置。通常情况下,我们通过服务端提供的 API 接口来获取表单的初始信息。 Binding our FormGroup model现在我们已经实例化了 FormGroup 模型,是时候绑定到对应的 DOM 元素上了。具体示例如下: <form novalidate [formGroup]="user"> <label> <span>Full name</span> <input type="text" placeholder="Your full name" formControlName="name"> </label> <div formGroupName="account"> <label> <span>Email address</span> <input type="email" placeholder="Your email address" formControlName="email"> </label> <label> <span>Confirm address</span> <input type="email" placeholder="Confirm your email address" formControlName="confirm"> </label> </div> <button type="submit">Sign up</button> </form> 现在 // JavaScript APIs FormGroup -> 'user' FormControl -> 'name' FormGroup -> 'account' FormControl -> 'email' FormControl -> 'confirm' // DOM bindings formGroup -> 'user' formControlName -> 'name' formGroupName -> 'account' formControlName -> 'email' formControlName -> 'confirm' 当使用模板驱动的表单时,为了获取 {{ user.value | json }} // { name: '',account: { email: '',confirm: '' }} Reactive submit跟模板驱动的表单一样,我们可以通过 <form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user"> ... </form> 需要注意的是,我们使用 export class SignupFormComponent { user: FormGroup; onSubmit({ value,valid }: { value: User,valid: boolean }) { console.log(value,valid); } } 上面代码中,我们使用 export class SignupFormComponent { user: FormGroup; onSubmit() { console.log(this.user.value,this.user.valid); } } 表单的数据绑定方式和提交逻辑已经介绍完了,是该介绍表单实际应用中,一个重要的环节 — 表单验证。 Reactive error validation接下来我们来为表单添加验证规则,首先我们需要从 ngOnInit() { this.user = new FormGroup({ name: new FormControl('',[Validators.required,Validators.minLength(2)]),account: new FormGroup({ email: new FormControl('',Validators.required),confirm: new FormControl('',Validators.required) }) }); } 通过以上示例,我们可以看出,如果表单控制包含多种验证规则,可以使用数组声明多种验证规则。若只包含一种验证规则,直接声明就好。通过这种方式,我们就不需要在模板的输入控件中添加 <form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user"> ... <button type="submit" [disabled]="user.invalid">Sign up</button> </form> 那么问题来了,我们要如何获取表单控件的验证信息?我们可以使用模板驱动表单中介绍的方式,具体如下: <form novalidate [formGroup]="user"> {{ user.controls.name?.errors | json }} </form>
此外我们也可以使用 <form novalidate [formGroup]="user"> {{ user.get('name').errors | json }} </form> 现在我们来看一下完整的代码: import { Component,FormGroup,Validators } from '@angular/forms'; import { User } from './signup.interface'; @Component({ selector: 'signup-form',template: ` <form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user"> <label> <span>Full name</span> <input type="text" placeholder="Your full name" formControlName="name"> </label> <div class="error" *ngIf="user.get('name').hasError('required') && user.get('name').touched"> Name is required </div> <div class="error" *ngIf="user.get('name').hasError('minlength') && user.get('name').touched"> Minimum of 2 characters </div> <div formGroupName="account"> <label> <span>Email address</span> <input type="email" placeholder="Your email address" formControlName="email"> </label> <div class="error" *ngIf="user.get('account').get('email').hasError('required') && user.get('account').get('email').touched"> Email is required </div> <label> <span>Confirm address</span> <input type="email" placeholder="Confirm your email address" formControlName="confirm"> </label> <div class="error" *ngIf="user.get('account').get('confirm').hasError('required') && user.get('account').get('confirm').touched"> Confirming email is required </div> </div> <button type="submit" [disabled]="user.invalid">Sign up</button> </form> ` }) export class SignupFormComponent implements OnInit { user: FormGroup; constructor() {} ngOnInit() { this.user = new FormGroup({ name: new FormControl('',account: new FormGroup({ email: new FormControl('',Validators.required) }) }); } onSubmit({ value,valid); } } 功能是实现了,但创建 Simplifying with FormBuilder首先我们需要从 import { FormBuilder,Validators } from '@angular/forms'; export class SignupFormComponent implements OnInit { user: FormGroup; constructor(private fb: FormBuilder) {} ... } 然后我们使用 调整前的代码 (未使用FormBuilder): ngOnInit() { this.user = new FormGroup({ name: new FormControl('',Validators.required) }) }); } 调整后的代码 (使用FormBuilder): ngOnInit() { this.user = this.fb.group({ name: ['',Validators.minLength(2)]],account: this.fb.group({ email: ['',Validators.required],confirm: ['',Validators.required] }) }); } 对比一下调整前和调整后的代码,是不是感觉一下子方便了许多。此时更新完后完整的代码如下: @Component({...}) export class SignupFormComponent implements OnInit { user: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.user = this.fb.group({ name: ['',account: this.fb.group({ email: ['',Validators.required] }) }); } onSubmit({ value,valid); } } 我有话说Template-Driven Forms vs Reactive FormsTemplate-Driven Forms (模板驱动表单) 的特点
Reactive Forms (响应式表单) 的特点
参考资源
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |