當表單結構相似,頻繁地使用響應式表單或許是一件增長工做量地事情,除了將模板進行合理地封裝,表單模型也要可以靈活地構造,此時推薦使用動態表單。
動態表單模板中,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文本,以及簡單的驗證器均動態化,保證了多條件下都可以提交和驗證表單。優化