angular学习之动态创建表单

发布时间:2019-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了angular学习之动态创建表单脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

准备工作

使用ng new async-form创建一个新工程,在app.module.ts中引入ReactiveFormsModule模块并在根模块中导入

import { ReactiveFormsModule } From '@Angular/forms';
@NgModule({
 imports: [
    ReactiveFormsModule
  ]
})

构建表单元素的基类

export class QuestionBase<T> {
    value: T;//表单元素的值
    key: string;//表单元素键的名称
    label: string;//输入元素的标题
    required: boolean;//是否必输
    order: number;//排序
    controlType: string;//表单的类型  选择框/文本输入框

    constructor(options: {
        value?: T,
        key?: string,
        label?: string,
        required?: boolean,
        order?: number,
        controlType?: string
    } = {}) {
        this.value = options.value;
        this.key = options.key || '';
        this.label = options.label || '';
        this.required = !!options.required;
        this.order = options.order === undefined ? 1 : options.order;
        this.controlType = options.controlType || '';
    }
}

继承表单元素的基类

选择框元素的数据类型继承基类,设置了controlType 为'dropdown'并新增了属性options数组

import { QuestionBase } from './question-base';

export class QuestionDropdown extends QuestionBase<string>{
    controlType = "dropdown";
    options: { key: string, value: string }[] = [];

    constructor(options: {} = {}) {
        super(options);
        this.options = options["options"] || [];
    }
}

文本输入框元素的数据类型继承了基类,设置了controlType 为'textbox',新增了type属性,定义input的类型

import { QuestionBase } from './question-base';

export class QuestionTextbox extends QuestionBase<string> {
    controlType = "textbox";
    type:string;
    constructor(options:{} ={}){
        super(options);
        this.type = options["type"]||""
    }
}

生成数据

根据表单元素的派生类生成表单的数据。可以引入一个服务类,提供表单数据。

  getQuestions(){
    let questions:QuestionBase<any>[]=[
      new QuestionDropdown({
        key:'brave',
        label:'Bravery Rating',
        options:[
          {key:'solid',value:'Solid'},
          {key:'great',value:'Great'},
          {key:'good',value:'Good'},
          {key:'unproven',value:'Unproven'}
        ],
        order:3
      }),
      new QuestionTextbox({
        key:'firstName',
        label:'First name',
        value:"Bombasto",
        required:true,
        order:1
      }),
      new QuestionTextbox({
        key:'emailAddress',
        label:"Email",
        type:'email',
        order:2
      })
    ];
    return questions.sort((a, b) => a.order - b.order);
  }

将数据转成FormControl类型

可以专门提供一个服务类,将表单的数据转成FormControl类型

  toFormGroup(questions: QuestionBase<any>[]) {
    let group: any = {};

    questions.forEach(question => {
      group[question.key] = question.required?new FormControl(question.value||"",Validators.required)
      :new FormControl(question.value||"");
    });
    return new FormGroup(group);
  }

到这里就已经完整构建出一组FormControl 实例了。

为数据提供页面模板

<div [formGroup]="form">
  <label [attr.for]="question.key">{{question.label}}</label>
  <div [ngSwitch]="question.controlType">
    <input *ngSwitchCase="'textbox'" [formControlName]= "question.key" 
    [id]="question.key" [type]="question.type">
    <select [id]="question.key" *ngSwitchCase="'dropdown'"
      [formControlName]="question.key">
      <option *ngFor="let opt of question.options" [value]="opt.key">
        {{opt.value}}
      </option>
    </select>
  </div>
  <div class="errorMessage" *ngIf="!isValid">
    {{question.label}} is required
  </div>
</div>

通过formGroup指令绑定表单数据,ngSwitch指令来选择生成的模板,formControlName指令绑定对应的表单数据的key值

import { Component, OnInit, Input } from '@angular/core';
import {FormGroup} from '@angular/forms';

import {QuestionBase} from '../question-base';

@Component({
  selector: 'app-dynamic-form-question',
  templateUrl: './dynamic-form-question.component.html',
  styleUrls: ['./dynamic-form-question.component.less']
})
export class DynamicFormQuestionComponent implements OnInit {
  @Input() question:QuestionBase<any>;
  @Input() form :FormGroup;
  get isValid(){
    return this.form.controls[this.question.key].valid;
  }
  constructor() { }

  ngOnInit() {
  }

}

表单组件需要两个输入,form和question,form来获取对应表单的键值是否校验成功,question来渲染对应表单输入元素。使用app-dynamic-form-question标签来使用组件

引用表单组件

    <div *ngFor="let question of questions" class="form-row">
      <app-dynamic-form-question [question]="question" [form]="form"></app-dynamic-form-question>
    </div>

获取到questions数据后,通过*ngFor指令来渲染单个表单组件。

结束

到这里就完成了动态创建表单的功能,以这种方式来创建表单,我们只需要开始时构建出指定的单个输入框或者其他表单元素的样式之后,通过改变数据来控制表单的内容,便于后期维护。

脚本宝典总结

以上是脚本宝典为你收集整理的angular学习之动态创建表单全部内容,希望文章能够帮你解决angular学习之动态创建表单所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。