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 相关文章推荐
js不是基础的基础
Dec 24 Javascript
javascript 日历提醒系统( 兼容所有浏览器 )
Apr 07 Javascript
Javascript学习笔记7 原型链的原理
Jan 11 Javascript
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
Dec 02 Javascript
JS 实现导航栏悬停效果(续)
Sep 24 Javascript
javascript计算星座属相(十二生肖属相)示例代码
Jan 09 Javascript
javascript继承机制实例详解
Nov 20 Javascript
js钢琴按钮波浪式图片排列效果代码分享
Aug 26 Javascript
微信小程序 图片加载(本地,网路)实例详解
Mar 10 Javascript
JS按钮闪烁功能的实现代码
Jul 21 Javascript
JavaScript变量类型以及变量作用域详解
Aug 14 Javascript
微信上传视频文件提示(推荐)
Nov 22 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_Cooikes不同页面无法传递的解决方法
2014/03/07 PHP
php smtp实现发送邮件功能
2017/06/22 PHP
在Ubuntu 18.04上安装PHP 7.3 7.2和7.0的方法
2019/04/09 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
js 表格隔行颜色
2009/12/02 Javascript
JavaScript中数组的排序、乱序和搜索实现代码
2011/11/30 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
JavaScript中字面量与函数的基本使用知识
2015/10/20 Javascript
用js制作淘宝放大镜效果
2020/10/28 Javascript
JavaScript中transform实现数字翻页效果
2017/03/08 Javascript
javascript 正则表达式分组、断言详解
2017/04/20 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
2020/01/08 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
微信小程序吸底区域适配iPhoneX的实现
2020/04/09 Javascript
微信小程序实现身份证取景框拍摄
2020/09/09 Javascript
[02:12]打造更好的电竞完美世界:完美盛典回顾篇
2018/12/19 DOTA
python文件读写操作与linux shell变量命令交互执行的方法
2015/01/14 Python
Python 数据结构之旋转链表
2017/02/25 Python
在python中使用正则表达式查找可嵌套字符串组
2017/10/24 Python
python+selenium识别验证码并登录的示例代码
2017/12/21 Python
python正则表达式去除两个特殊字符间的内容方法
2018/12/24 Python
PyCharm更改字体和界面样式的方法步骤
2019/09/27 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
Anaconda使用IDLE的实现示例
2020/09/23 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
2020/10/18 Python
Python实现Kerberos用户的增删改查操作
2020/12/14 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
2020/12/17 Python
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
安全生产承诺书范文
2014/05/22 职场文书
我的大学四年规划书范文2014
2014/09/26 职场文书
副总经理岗位职责范本
2014/09/30 职场文书
幼儿园辞职书
2015/02/26 职场文书
Go Gin实现文件上传下载的示例代码
2021/04/02 Golang
pytorch 6 batch_train 批训练操作
2021/05/28 Python