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 相关文章推荐
utf8的编码算法 转载
Dec 27 Javascript
Javascript 日期处理之时区问题
Oct 08 Javascript
JQuery点击行tr实现checkBox选中的简单实例
May 26 Javascript
Node.js读写文件之批量替换图片的实现方法
Sep 07 Javascript
JQuery 进入页面默认给已赋值的复选框打钩
Mar 23 jQuery
微信小程序 数据遍历的实现
Apr 05 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
vue-router结合vuex实现用户权限控制功能
Nov 14 Javascript
微信小程序 (地址选择1)--选取搜索地点并显示效果
Dec 17 Javascript
js实现多图和单图上传显示
Dec 18 Javascript
Vue中使用Lodop插件实现打印功能的简单方法
Dec 19 Javascript
如何用JS实现网页瀑布流布局
Apr 24 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
UCenter 批量添加用户的php代码
2012/07/17 PHP
解析关于wamp启动是80端口被占用的问题
2013/06/21 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
PHP中危险的file_put_contents函数详解
2017/11/04 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
使一个函数作为另外一个函数的参数来运行的javascript代码
2007/08/13 Javascript
Extjs学习笔记之二 初识Extjs之Form
2010/01/07 Javascript
treepanel动态加载数据实现代码
2012/12/15 Javascript
JS实现点击图片在当前页面放大并可关闭的漂亮效果
2013/10/18 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
2015/11/16 Javascript
微信小程序 picker-view 组件详解及简单实例
2017/01/10 Javascript
JavaScript利用Date实现简单的倒计时实例
2017/01/12 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
Angular移动端页面input无法输入的解决方法
2017/11/14 Javascript
AngularJS中重新加载当前路由页面的方法
2018/03/09 Javascript
深入理解NodeJS 多进程和集群
2018/10/17 NodeJs
解决vue cli4升级sass-loader(v8)后报错问题
2020/07/30 Javascript
vue 自定指令生成uuid滚动监听达到tab表格吸顶效果的代码
2020/09/16 Javascript
解决vant框架做H5时踩过的坑(下拉刷新、上拉加载等)
2020/11/11 Javascript
tensorflow学习笔记之mnist的卷积神经网络实例
2018/04/15 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
解决nohup执行python程序log文件写入不及时的问题
2019/01/14 Python
python flask中动态URL规则详解
2019/11/22 Python
Tensorflow矩阵运算实例(矩阵相乘,点乘,行/列累加)
2020/02/05 Python
python3获取控制台输入的数据的具体实例
2020/08/16 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
分享一个H5原生form表单的checkbox特效代码
2018/02/26 HTML / CSS
Dr. Martens马汀博士德国官网:马丁靴鼻祖
2019/12/26 全球购物
给校长的建议书100字
2014/05/16 职场文书
合作意向协议书
2015/01/29 职场文书
生日宴会祝酒词
2015/08/10 职场文书
2019学子的答谢词范本!
2019/07/05 职场文书
windows10声卡驱动怎么安装?win10声卡驱动安装操作步骤教程
2022/08/05 数码科技