Angular5通过从数据库中获取字段名称和选项来创建表单

时间:2018-03-27 19:21:11

标签: javascript angular

在角度5中,我有来自数据库的数据,如此

data = [
{type: 'radio', label: 'gender', options: 'male,female', required: 'yes' }
{type: 'input', label: 'first name', options: '' }
{type: 'select', label: 'country', options: 'india,pak,sri lanka' }
]

我想创建一个使用这些数据。我已决定将其设置为formarray,以便我可以通过验证轻松地将值保存到数据库中。所以我为此制作了我的代码

import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-registration-checkout',
  templateUrl: './registration-checkout.component.html',
  styleUrls: ['./registration-checkout.component.css']
})

export class RegistrationCheckoutComponent implements OnInit {
constructor(
    private http: HttpClient,
    private formBuilder : FormBuilder,
    ) {}

ngOnInit() {
    this.checkOutService.getExtraFields().subscribe( response => {
      this.fields = (response['fields']);
      console.log(this.fields); //Here I am getting the data in json format what I have explained above
    },
    err => {
      console.log(err);
    });
}

initSection() {
    return new FormGroup({
        //here I have to make something with the data
    });
}

addSection() {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection());
  }

 getSections(form) {
    return form.controls.sections.controls;
  }

但我不知道如何在initSection中使用这些数据,以便使用验证功能轻松创建表单。   有人能告诉我该怎么做吗?任何帮助和建议都会非常明显。感谢

更新代码

import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-registration-checkout',
  templateUrl: './registration-checkout.component.html',
  styleUrls: ['./registration-checkout.component.css']
})

export class RegistrationCheckoutComponent implements OnInit {
constructor(
    private http: HttpClient,
    private formBuilder : FormBuilder,
    ) {}

    ngOnInit() {
        this.eventService.getEvent(eventid).subscribe( response => {
            this.Data = eval(response.fields);
            console.log(this.Data);
        });

        let plainObject = {}
        this.Data.map((field)=>{
            plainObject[field.label] = new FormControl('')
        });

        this.dynamicForm = this.formBuilder.group(plainObject)
    }
}

我的模板看起来像这样

<div class="field" *ngFor="let field of Data ">
  <div class="form-group col-2" *ngIf="field.type ==='input'">
    <label for="{{field.label}}">{{field.label}}</label>
    <input type="text" class="form-control" autocomplete="off" placeholder="First Name" formControlName="{{field.label}}">
  </div>
  <div class="form-group col-2" *ngIf='field.type=="radio"'>
    <label for="{{field.label}}">{{field.label}}</label>
    <input type="radio" name="{{field.label}}">
  </div> 
  <div class="form-group col-2" *ngIf="field.type ==='select'">
    <label for="{{field.label}}">{{field.label}}</label>
        <select class="" formControlName="{{field.label}}" >
        <option *ngFor="let option of field.options.split(',')" [value]="option">{{ option }}</option>
      </select>
  </div>

  <div class="form-group col-2" *ngIf="field.type ==='radio'">
    <label for="{{field.label}}">{{field.label}}</label>
    <ng-container *ngFor="let option of field.options.split(',')">
        <input type="radio" [name]="option"> {{ option }}
    </ng-container>
  </div>
</div>

如果我使用的是我从服务中得到的值不起作用。服务可能会在一段时间后获取数据,并且表单已经初始化了。

1 个答案:

答案 0 :(得分:0)

您正在寻找的概念是动态表单,是一种根据您从后端接收的数据处理和构建表单的方法

假设您要构建一个反应形式,而您拥有的唯一数据就是此数组

data = [
{type: 'radio', label: 'gender', options: 'male,female', required: 'yes' }
{type: 'input', label: 'first name', options: '' }
{type: 'select', label: 'country', options: 'india,pak,sri lanka' }
]

在视图中,您现在不需要字段的数量和类型,这就是为什么需要循环遍历字段数组并以动态方式构建模板

<form class="form-group" [formGroup]="dynamicForm">
   <div class="field" *ngFor="let field of data">
     <input type="{{field.type}}" [formControlName]="field.label">
     // here is where the magic happens , based on the kind of field you 
     // need to create your custom types populated with specific values 
   </div>
 </form>

我建议您创建实现ControlValueAccessor界面的自定义组件(可帮助您创建自定义反应表单的界面) 并将对象field传递给此动态表单输入

所以如何建立反应形式dynamicForm

这个想法与模板相同:

遍历所有字段并设置对象的名称并声明表单控件值,使用FormBuilder类来帮助您构造表单

假设field.label是您的表单字段的ID

private fb: FormBuilder // import this on the constructor
let plainObject = {}
data.map((field)=>{
  plainObject[field.label] = this.fb.control(field.value,[/**include here the validators*/])
})
this.dynamicForm = this.fb.group(plainObject)

field.value是我用来设置表单默认值的示例,我现在不是您数据的真实结构

这是您可以遵循的方法

更新新代码

您可以开始改进ngOnInit上的代码 一旦来自后端的响应到达,您只会收到您的数据,因此您的代码应如下所示

ngOnInit() {
    this.eventService.getEvent(eventid).subscribe( response => {
        this.Data = eval(response.fields);
        let plainObject = {}
        this.Data.map((field)=>{
           plainObject[field.label] = new FormControl('')
        });

        this.dynamicForm = this.formBuilder.group(plainObject)
    });


}

否则动态形式永远不会被初始化