angular学习之动态创建表单的方法


Posted in Javascript onDecember 07, 2018

准备工作

使用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指令来渲染单个表单组件。

结束

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 学习之二 属性 文本与值(text,val)
Nov 25 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
Nov 03 Javascript
js获取微信版本号的方法
May 12 Javascript
自定义刻度jQuery进度条及插件
Sep 02 Javascript
JavaScript优化专题之Loading and Execution加载和运行
Jan 20 Javascript
javaScript数组迭代方法详解
Apr 14 Javascript
利用vue实现模态框组件
Dec 19 Javascript
ionic+AngularJs实现获取验证码倒计时按钮
Apr 22 Javascript
angular实现页面打印局部功能的思考与方法
Apr 13 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
Aug 31 Javascript
Vue数据绑定实例写法
Aug 06 Javascript
小程序中手机号识别的示例
Dec 14 Javascript
JavaScript栈和队列相关操作与实现方法详解
Dec 07 #Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
Dec 07 #Javascript
vue webpack打包后图片路径错误的完美解决方法
Dec 07 #Javascript
详解在create-react-app使用less与antd按需加载
Dec 06 #Javascript
vant(ZanUi)结合async-validator实现表单验证的方法
Dec 06 #Javascript
使用react render props实现倒计时的示例代码
Dec 06 #Javascript
微信小程序冒泡事件及其阻止方法实例分析
Dec 06 #Javascript
You might like
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-1 开始了解php
2011/07/03 PHP
php线性表顺序存储实现代码(增删查改)
2012/02/16 PHP
PHP登陆后跳转到登陆前页面实现思路及代码
2014/01/17 PHP
封装ThinkPHP的一个文件上传方法实例
2014/10/31 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
详谈phpAdmin修改密码后拒绝访问的问题
2017/04/03 PHP
PHP中trait使用方法详细介绍
2017/05/21 PHP
URI、URL和URN之间的区别与联系
2006/12/20 Javascript
window.location和document.location的区别分析
2008/12/23 Javascript
JS 页面自动加载函数(兼容多浏览器)
2009/05/18 Javascript
js控制frameSet示例
2013/09/10 Javascript
jQuery中live()方法用法实例
2015/01/19 Javascript
javascript常用的方法分享
2015/07/01 Javascript
JS实现超简单的汉字转拼音功能示例
2016/12/22 Javascript
详解nodejs express下使用redis管理session
2017/04/24 NodeJs
jQuery实现radio第一次点击选中第二次点击取消功能
2017/05/15 jQuery
最适应的vue.js的form提交涉及多种插件【推荐】
2018/08/27 Javascript
jquery无缝图片轮播组件封装
2020/11/25 jQuery
快速了解Node中的Stream流是什么
2019/02/13 Javascript
elementUI多选框反选的实现代码
2019/04/03 Javascript
微信小程序转发事件实现解析
2019/10/22 Javascript
JavaScript canvas绘制圆弧与圆形
2020/02/18 Javascript
解析Python中的__getitem__专有方法
2016/06/27 Python
Python入门之三角函数tan()函数实例详解
2017/11/08 Python
Python SQLite3简介
2018/02/22 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
Python多进程原理与用法分析
2018/08/21 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
Python hmac模块使用实例解析
2019/12/24 Python
canvas绘制树形结构可视图形的实现
2020/04/03 HTML / CSS
消防安全汇报材料
2014/02/08 职场文书
入党转正申请报告
2015/05/15 职场文书
谢师宴家长致辞
2015/07/27 职场文书
办公室管理规章制度
2015/08/04 职场文书
2019初中学生入团申请书
2019/06/27 职场文书
确保减税降费落地生根,用实实在在措施
2019/07/19 职场文书