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

准备工作

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

结束

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

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

(0)

相关推荐

  • Angular 4.x 动态创建表单实例

    本文将介绍如何动态创建表单组件,我们最终实现的效果如下: 在阅读本文之前,请确保你已经掌握 Angular 响应式表单和动态创建组件的相关知识,如果对相关知识还不了解,推荐先阅读一下 Angular 4.x Reactive Forms和 Angular 4.x 动态创建组件 这两篇文章.对于已掌握的读者,我们直接进入主题. 创建动态表单 创建 DynamicFormModule 在当前目录先创建 dynamic-form 目录,然后在该目录下创建 dynamic-form.module.ts

  • angular动态表单制作

    源码:https://github.com/Karin001/ngx-dynamic-form 动态表单使用场景 有时候我们需要一个灵活的表单,这个表单可以根据用户的选择,或者服务器返回的信息进行重新配置,比如:增加或删除一组input元素.一组select元素,等等. 在这样的情况下,如果一开始就在模板里写下所有的表单,利用一个ngif树状结构进行选择控制,程序会变得比较冗余. 这时.程序最好是能够根据用户的选择(driven by configuration)或者服务器的响应,自动生成所需要

  • Angular4实现动态添加删除表单输入框功能

    首先介绍一下实现的效果,就是单一表单能实现添加其他的,也能删除 代码如下: <h5>动态添加表单</h5> <div class="form"> <div class="form-group form-group-sm" *ngFor="let i of login"> <label class="col-form-label">用户名</label> &

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

    准备工作 使用ng new async-form创建一个新工程,在app.module.ts中引入ReactiveFormsModule模块并在根模块中导入 import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ ReactiveFormsModule ] }) 构建表单元素的基类 export class QuestionBase<T> { value: T;//表单元素的值 key: stri

  • Yii2创建表单(ActiveForm)方法详解

    本文实例讲述了Yii2创建表单(ActiveForm)的方法.分享给大家供大家参考,具体如下: 由于表单涉及到一些验证方面的信息,属性设置又比较多.比较复杂,所以哪里有什么不正确的地方请留言指点 目录 表单的生成 表单中的方法   ActiveForm::begin()方法   ActiveForm::end()方法   getClientOptions()方法   其它方法:errorSummary.validate.validateMultiple 表单中的参数   表单form自身的属性

  • 如何使用Bootstrap创建表单

    Bootstrap 表单 在本章中,我们将学习如何使用 Bootstrap 创建表单.Bootstrap 通过一些简单的 HTML 标签和扩展的类即可创建出不同样式的表单. 垂直或基本表单 基本的表单结构是 Bootstrap 自带的,个别的表单控件自动接收一些全局样式.下面列出了创建基本表单的步骤: - 向父 <form> 元素添加 role="form". - 把标签和控件放在一个带有 class .form-group 的 中.这是获取最佳间距所必需的. - 向所有的

  • javascript创建动态表单的方法

    本文实例讲述了javascript创建动态表单的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

  • Angular 4根据组件名称动态创建出组件的方法教程

    一.理解angular组件 组件是一种特殊的指令,使用更简单的配置项来构建基于组件的应用程序架构,这样他能简单地写app,通过类似的web Component 或者angular2的样式.web Component 是一个规范.马上就要成为标准. 应用组件的优点: 比普通指令配置还简单 提供更好的默认设置和最好的实践 对基于组建的应用架构更优化. 对angular2的升级更平滑. 不用组建的情况: 对那些在 compile或者pre-link阶段要执行操作的指令,组件不能用,因为无法到达那个阶段

  • 详解Angular 4.x 动态创建组件

    动态创建组件 这篇文章我们将介绍在 Angular 中如何动态创建组件. 定义 AlertComponent 组件 首先,我们需要定义一个组件. exe-alert.component.ts import { Component, Input } from '@angular/core'; @Component({ selector: "exe-alert", template: ` <h1>Alert {{type}}</h1> `, }) export cl

  • 详解Bootstrap创建表单的三种格式(一)

    在本章中,我们将学习如何使用 Bootstrap 创建表单.Bootstrap 通过一些简单的 HTML 标签和扩展的类即可创建出不同样式的表单.  Bootstrap表单类型分为三种格式:垂直或基本表单.内联表单.水平表单. 垂直或基本表单(display:block;) 基本的表单结构是 Bootstrap 自带的,个别的表单控件自动接收一些全局样式.下面列出了创建基本表单的步骤: 向父 <form> 元素添加 role="form". 把标签和控件放在一个带有 cla

  • javascript实现的动态添加表单元素input,button等(appendChild)

    写一个小系统时,需要动态添加表单元素,按自己的实现方法写了这篇教程! 我想各位在很多网站上都看到过类似的效果! 1.先用document.createElement方法创建一个input元素! 复制代码 代码如下: var newInput = document.createElement("input"); 2.设定相关属性,如name,type等  复制代码 代码如下: newInput.type=mytype;   newInput.name="input1"

  • vue构建动态表单的方法示例

    概述 后台管理系统里面有非常多的表单需求,我们希望能够通过写一个json格式的数据,通过vue的循环动态地去渲染动态表单.并且能够在外部得到渲染出来的表单的数据,可以对表单进行重置操作.我结合element ui的控件的下拉框,输入框,时间选择控件和vue-treeselect,做了一个动态表单. v-model的理解 先简单讲一下vue-model是怎么玩的.其实vue-model相当于给表单元素传递一个value,外部监听input事件.所以我们自己封装表单组件的时候也是可以传递一个valu

随机推荐