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实现页面自适应
Jan 19 Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
Dec 02 Javascript
移动节点的jquery代码
Jan 13 Javascript
javascript中的事件代理初探
Mar 08 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
Sep 06 Javascript
node.js超时timeout详解
Nov 26 Javascript
d3.js中冷门却实用的内置函数总结
Feb 04 Javascript
Async Validator 异步验证使用说明
Jul 03 Javascript
最新Javascript程序员面试试题和解题方法
Nov 23 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
Feb 07 Javascript
JavaScript实现多文件下载方法解析
Aug 07 Javascript
详解vue 组件注册
Nov 20 Vue.js
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 中执行排序与 MySQL 中排序
2009/04/21 PHP
php中动态修改ini配置
2014/10/14 PHP
smarty模板引擎基础知识入门
2015/03/30 PHP
图像替换新技术 状态域方法
2010/01/28 Javascript
基于mootools 1.3框架下的图片滑动效果代码
2011/04/22 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
js中函数调用的两种常用方法使用介绍
2014/07/17 Javascript
简单的jquery左侧导航栏和页面选中效果
2014/08/21 Javascript
浅谈Vue.js
2017/03/02 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
JavaScript解析任意形式的json树型结构展示
2017/07/23 Javascript
解决axios发送post请求返回400状态码的问题
2018/08/11 Javascript
vue-router的HTML5 History 模式设置
2018/09/08 Javascript
vue+iview/elementUi实现城市多选
2019/03/28 Javascript
详解JS实现简单的时分秒倒计时代码
2019/04/25 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
Bootstrap简单实用的表单验证插件BootstrapValidator用法实例详解
2020/03/29 Javascript
uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果
2020/12/10 Javascript
[01:18:33]Secret vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
Python的爬虫包Beautiful Soup中用正则表达式来搜索
2016/01/20 Python
python 读写文件,按行修改文件的方法
2018/07/12 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
Python实现数值积分方式
2019/11/20 Python
python之生成多层json结构的实现
2020/02/27 Python
独特的礼品和创新的科技产品:The Grommet
2018/02/24 全球购物
求网格中的黑点分布
2013/11/06 面试题
质量工程师岗位职责
2013/11/16 职场文书
给幼儿园老师的表扬信
2014/01/19 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
技能比武方案
2014/05/21 职场文书
2014年纳税评估工作总结
2014/12/23 职场文书
余世维讲座观后感
2015/06/11 职场文书
社会实践心得体会范文
2016/01/14 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL
教你win10系统中APPCRASH事件问题解决方法
2022/07/15 数码科技