当表单结构相似,频繁地使用响应式表单或许是一件增长工做量地事情,除了将模板进行合理地封装,表单模型也要可以灵活地构造,此时推荐使用动态表单。
动态表单模板中,value、label均动态化,表单字段也是动态绑定,比较基础地模型是一个数组循环与模板绑定处理;生成一个formGroup,会根据不一样地类型区分,此时不包含重复项。数据模型数据:
css
this.base = [ { key: 'userName', label: '姓名', value: null, validators: [Validators.required] }, { key: 'age', label: '年龄', value: null, validators: [Validators.required] } ];
form生成:
html
this.form = this.toFormGroup(this.base); toFormGroup(options: any[]) { const group = {}; options.forEach(item => { group[item.key] = new FormControl(item.value, item.validators); }); return new FormGroup(group); }
模板
数组
<form nz-form [formGroup]="form" (ngSubmit)="submit(form)"> <div *ngFor="let item of base"> <ng-container [formGroup]="form"> <div nz-row nzFlex [nzGutter]="8"> <div nz-col [nzSpan]="6"> <nz-form-item> <nz-form-label [nzSpan]="10">{{item.label}}</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input type="text" [formControlName]="item.key" placeholder="Enter Your Working date..." /> </nz-form-control> </nz-form-item> </div> </div> </ng-container> </div> </form>
模板组件化,方法服务化basic-form
app
<form nz-form [formGroup]="form" (ngSubmit)="submit(form)"> <ng-container [formGroup]="form"> <div nz-row nzFlex [nzGutter]="8"> <div nz-col [nzSpan]="6" *ngFor="let item of base"> <nz-form-item> <nz-form-label [nzSpan]="10">{{item.label}}</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input type="text" [formControlName]="item.key" placeholder="{{item.placeholder}}" /> </nz-form-control> </nz-form-item> </div> </div> </ng-container> </form>
咱们须要实现一个根据不一样学龄阶段的学生生成不一样的某个申请表单,这时表单须要动态化处理,
修改代码:
view.component.htmlide
<div nz-row nzGutter="16"> <div nz-col nzSpan="24"> <nz-radio-group [(ngModel)]="grade" (ngModelChange)="gradeChange($event)"> <label nz-radio-button nzValue="junior"><span>小学</span></label> <label nz-radio-button nzValue="middle"><span>初中</span></label> <label nz-radio-button nzValue="high"><span>高中</span></label> </nz-radio-group> </div> </div> <section class="form-container"> <basic-form [form]="form" [data]="formData"></basic-form> </section>
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators, FormArray, FormControl, ValidationErrors, ValidatorFn } from '@angular/forms'; import { FormService } from '../share/form.service'; interface FormFieldObject { key: string; label: string; value: any; placeholder: string; validators: ValidatorFn[]; } @Component({ selector: 'app-view', templateUrl: './view.component.html', styleUrls: ['./view.component.scss'] }) export class ViewComponent implements OnInit, AfterViewInit { constructor( private formService: FormService ) { } form: FormGroup; formData: FormFieldObject[]; base: FormFieldObject[]; grade = 'junior'; ngOnInit() { this.base = [ { key: 'userName', label: '姓名', value: null, placeholder: 'Enter Your Name', validators: [Validators.required] }, { key: 'age', label: '年龄', value: null, placeholder: 'Enter Your Age', validators: [Validators.required] } ]; this.formData = [...this.base]; this.form = this.formService.createForm(this.formData); } gradeChange(event) { this.base = [ { key: 'userName', label: '姓名', value: null, placeholder: 'Enter Your Name', validators: [Validators.required] }, { key: 'age', label: '年龄', value: null, placeholder: 'Enter Your Age', validators: [Validators.required] } ]; if (event === 'middle') { const pre = [ { key: 'junior', label: '小学教育', value: null, placeholder: 'Enter Your junior school', validators: [Validators.required] } ]; this.formData = [...this.base, ...pre]; this.form = this.formService.createForm(this.formData); } else if (event === 'junior') { this.formData = [...this.base]; this.form = this.formService.createForm(this.formData); } else { const pre = [ { key: 'junior', label: '小学教育', value: null, placeholder: 'Enter Your junior school', validators: [Validators.required] }, { key: 'middle', label: '初中教育', value: null, placeholder: 'Enter Your middle school', validators: [Validators.required] } ]; this.formData = [...this.base, ...pre]; this.form = this.formService.createForm(this.formData); } } ngAfterViewInit() { } }
import { Injectable } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; @Injectable({ providedIn: 'root' }) export class FormService { constructor() { } createForm(arrays: any[]) { const group = {}; arrays.forEach(item => { group[item.key] = new FormControl(item.value, item.validators); }); return new FormGroup(group); } }
模板组件组件化
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core'; import { FormGroup } from '@angular/forms'; @Component({ // tslint:disable-next-line: component-selector selector: 'basic-form', templateUrl: './basic-form.component.html', styleUrls: ['./basic-form.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class BasicFormComponent implements OnInit { @Input() form: FormGroup; @Input() data: any[]; constructor() { } ngOnInit() { } submit() { console.log(this.form.valid); } }
将表单控件的value、字段、placeholder文本,以及简单的验证器均动态化,保证了多条件下都可以提交和验证表单。优化