Angular响应式表单--附上完整代码演示
Angular响应式表单--文后附上完整代码演示
响应式表单—单个控件
a) 根模块app-.module.ts导入ReactiveFormsModule
import {ReactiveFormsModule} from '@angular/forms';
b) 组件NameEditor使用时引入FormControl表单控件,并创建实例
name=new FormControl(‘请输入名字’);
c) 表单绑定
<input type="text" [formControl]="name">
d) 获取表单控件值:{{ name.value }}
e) 设置表单控件值:this.name.setValue('Nancy');
响应式表单—控件组
a) 导入ReactiveFormsModule
b) 组件导入import { FormControl,FormGroup} from '@angular/forms';
c) 创建实例化对象及页面显示
profileGroup=new FormGroup(
{
firstName:new FormControl("fname"),
lastName:new FormControl("lname"),
}
);
<form [formGroup]="profileGroup" (ngSubmit)="onSubmit()">
<label>
First Name:
<input type="text" formControlName="firstName">
</label>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
<button type="submit" [disabled]="!profileGroup.valid">submit</button>
</form>
d) FormGroup 指令会监听 form 元素发出的 submit 事件,并使用回调函数做出反应
对应方法:在控制台上可以看见所提交的数据
onSubmit() {
console.warn(this.profileGroup.value);
}
响应式表单—嵌套式
a) 在profileGroup中嵌入一个FormGroup对象
profileGroup=new FormGroup( { firstName:new FormControl(''), lastName:new FormControl(''), address:new FormGroup({ street: new FormControl(''), city: new FormControl(''), }) } );
b) HTML文件修改,嵌入profileGroup表单里
<div formGroupName="address"> <h3>Address</h3> <label> Street: <input type="text" formControlName="street"> </label> <label> City: <input type="text" formControlName="city"> </label> </div>
c) 更新模型部分数据patchValue
this.profileGroup.patchValue({ firstName: 'Nancy', address: { street: '123 Drew Street' } })
响应式表单—嵌套式--使用FormBuilder创建表单组
a) 组件引入import { FormBuilder } from '@angular/forms';
b) 注入依赖constructor(private fb: FormBuilder) { }
c) 实例化FormGroup对象,使用group函数
profileForm = this.fb.group({ firstName: [''], lastName: [''], address: this.fb.group({ street: [''], city: [''], }), });
表单验证
a) 表单引入验证器import { Validators } from '@angular/forms';
b) 设置必需属性:
firstName: ['',Validators.required]
或者
<input type="text" formControlName="firstName" required>
c) 表单控件上添加了一个必填字段时,它的初始值是无效的(invalid)。这种无效状态会传播到其父 FormGroup 元素中,也让这个 FormGroup 的状态变为无效的,因此页面加载后,submit按钮是不可用的,当输入firstName时,又变成可用的
动态表单的创建
a) 使用FormBuilder创建表单数组,并可在页面已经加载后增加其内的表单控件
aliases: this.fb.array([//表单数组,可变 this.fb.control('') ])
b) 使用get方法来获得FromArry类型的表单数组
当点击添加按钮时,使用push动态地向数组内添加控件
get aliases() { return this.profileForm.get('aliases') as FormArray; }
addAlias(): void {
this.aliases.push(this.fb.control(''));
}
c) 在页面中加载
<div formArrayName="aliases">
完整代码
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import {ReactiveFormsModule} from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { NameEditorComponent } from './components/name-editor/name-editor.component'; import { ProfileEditorComponent } from './components/profile-editor/profile-editor.component'; @NgModule({ declarations: [ AppComponent, NameEditorComponent, ProfileEditorComponent ], imports: [ BrowserModule, AppRoutingModule, ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
app.module.html
<app-name-editor></app-name-editor> <br> <hr> <br> <app-profile-editor></app-profile-editor> <router-outlet></router-outlet>
name-editor.component.ts
import { Component, OnInit } from '@angular/core'; import { FormControl} from '@angular/forms'; @Component({ selector: 'app-name-editor', templateUrl: './name-editor.component.html', styleUrls: ['./name-editor.component.css'] }) export class NameEditorComponent implements OnInit { name=new FormControl('请输入名字'); constructor() { } ngOnInit(): void { } updateName() { this.name.setValue('Nancy'); } }
name-editor.component.html
<label> Name: <input type="text" [formControl]="name"> </label> <p> Value: {{ name.value }} </p> <button (click)="updateName()">Update Name</button>
profile-editor.component.ts
import { Component, OnInit } from '@angular/core'; import { FormControl,FormGroup} from '@angular/forms'; import { FormBuilder } from '@angular/forms'; import { Validators } from '@angular/forms';//验证器 import { FormArray } from '@angular/forms'; @Component({ selector: 'app-profile-editor', templateUrl: './profile-editor.component.html', styleUrls: ['./profile-editor.component.css'] }) export class ProfileEditorComponent implements OnInit { //表单组 profileGroup=new FormGroup( { firstName:new FormControl(''), lastName:new FormControl(''), address:new FormGroup({//表单组,不可变 street: new FormControl(''), city: new FormControl(''), }), } ); // 使用FormBuilder创建表单组 profileForm = this.fb.group({ firstName: ['',Validators.required], lastName: [''], address: this.fb.group({ street: [''], city: [''], }), aliases: this.fb.array([//表单数组,可变 this.fb.control('') ]) }); constructor(private fb: FormBuilder) { } ngOnInit(): void { } onSubmit() { console.warn(this.profileGroup.value); } updateProfile() { this.profileGroup.patchValue({ firstName: 'Nancy', address: { street: '123 Drew Street' } }); } get aliases() { return this.profileForm.get('aliases') as FormArray; } addAlias() { this.aliases.push(this.fb.control('')); } }
profile-editor.component.html
<form [formGroup]="profileGroup" (ngSubmit)="onSubmit()"> <label> First Name: <input type="text" formControlName="firstName"> </label> <label> Last Name: <input type="text" formControlName="lastName"> </label> <div formGroupName="address"> <h3>Address</h3> <label> Street: <input type="text" formControlName="street"> </label> <label> City: <input type="text" formControlName="city"> </label> </div> <button type="submit" [disabled]="!profileGroup.valid">submit</button> </form> <button (click)="updateProfile()">Update Profile</button> <hr> <br> <h2> 使用FormBuilder创建表单组</h2> <form [formGroup]="profileForm" (ngSubmit)="onSubmit()"> <label> First Name: <input type="text" formControlName="firstName"> </label> <label> Last Name: <input type="text" formControlName="lastName"> </label> <div formGroupName="address"> <h3>Address</h3> <label> Street: <input type="text" formControlName="street"> </label> <label> City: <input type="text" formControlName="city"> </label> </div> <div formArrayName="aliases"> <h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button> <div *ngFor="let alias of aliases.controls; let i=index"> <!-- The repeated alias template --> <label> Alias: <input type="text" [formControlName]="i"> </label> </div> </div> <button type="submit" [disabled]="!profileForm.valid">submit</button> </form> <!-- profileForm的状态 --> <p> Form Status: {{ profileForm.status }} </p>