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 相关文章推荐
JavaScript 判断浏览器类型及版本
Feb 21 Javascript
jquery ajax 同步异步的执行 return值不能取得的解决方案
Jan 08 Javascript
js获取class的所有元素
Mar 28 Javascript
深入探秘jquery瀑布流的实现
Jan 30 Javascript
Jquery ui datepicker设置日期范围,如只能隔3天【实现代码】
May 04 Javascript
JS判断日期格式是否合法的简单实例
Jul 11 Javascript
手机端实现Bootstrap简单图片轮播效果
Oct 13 Javascript
jQuery实现元素的插入
Feb 27 Javascript
Node.js学习教程之HTTP/2服务器推送【译】
Oct 31 Javascript
node.js通过axios实现网络请求的方法
Mar 05 Javascript
Electron中实现大文件上传和断点续传功能
Oct 28 Javascript
vue实现五子棋游戏
May 28 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 数据库树的遍历方法
2009/02/06 PHP
新浪中用来显示flash的函数
2007/04/02 Javascript
jQuery拖拽 &amp; 弹出层 介绍与示例
2013/12/27 Javascript
nodejs中使用monk访问mongodb
2014/07/06 NodeJs
jQuery新窗口打开外链接
2016/07/21 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
2016/08/01 Javascript
基于HTML5+JS实现本地图片裁剪并上传功能
2017/03/24 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
Angular中支持SCSS的方法
2017/11/18 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
Vue下路由History模式打包后页面空白的解决方法
2018/06/29 Javascript
vue鼠标移入添加class样式,鼠标移出去除样式(active)实现方法
2018/08/22 Javascript
Angular事件之不同组件间传递数据的方法
2018/11/15 Javascript
React如何实现浏览器打印部分内容详析
2019/05/19 Javascript
extjs图表绘制之条形图实现方法分析
2020/03/06 Javascript
解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题
2020/09/11 Javascript
浅谈Vue使用Elementui修改默认的最快方法
2020/12/05 Vue.js
Python urllib、urllib2、httplib抓取网页代码实例
2015/05/09 Python
python字符串连接方法分析
2016/04/12 Python
Python操作csv文件实例详解
2017/07/31 Python
Python 实现字符串中指定位置插入一个字符
2018/05/02 Python
Python smtplib实现发送邮件功能
2018/05/22 Python
django 装饰器 检测登录状态操作
2020/07/02 Python
Python中BeautifulSoup通过查找Id获取元素信息
2020/12/07 Python
应征英语教师求职信
2013/11/27 职场文书
纺织工程专业个人求职信范文
2014/01/27 职场文书
记帐员岗位责任制
2014/02/08 职场文书
端午节活动策划方案
2014/03/09 职场文书
法学专业毕业生自荐信
2014/06/11 职场文书
2014年秋季开学典礼主持词
2014/08/02 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
幼儿园2016年圣诞活动总结
2016/03/31 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
python之json文件转xml文件案例讲解
2021/08/07 Python
POST提交数据常见的四种方式
2022/01/18 HTML / CSS