Angular5通过从数据库获取字段名称和选项来创建表单 [英] Angular5 create form by getting the field name and options from the database

查看:40
本文介绍了Angular5通过从数据库获取字段名称和选项来创建表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在角度5中,我有像这样来自数据库的数据

In angular 5 I have the data which is coming from the database like this

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一样,以便可以通过验证轻松地将值保存到数据库中.因此,我已经将我的代码制作成这样

I want to create a from using those data. I have decided to make it as like a formarray so that I can easily save the values into the database easily with validation. So for that I have made my code like this

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中使用这些数据,以便它可以通过验证功能轻松创建表单. 有人可以告诉我该怎么做吗?任何帮助和建议将是非常可观的.谢谢

But I don't know how can I use those data in initSection so that it would create the form easily with validation functionality. So can someone tell me how to do that? Any help and suggestions will be really appreciable. Thanks

更新代码

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>

如果我使用的是从服务中获得的值,则无法正常工作.可能是该服务在一段时间后获取了数据,这意味着表单已经初始化.

If I am using the values what I have got from service is not working. Might be the service is getting data after some time and in that mean time the form has initialised.

推荐答案

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

the concept your are looking for is dynamic forms, is a way to handle and build forms from data that are you receiving from the backend

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

let say you want to build a reactive form and the only data you have is this array

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' }
]

在视图中,您现在没有字段数和类型,这就是为什么您需要遍历字段数组并动态构建模板的原因

in the view you dont now the number of fields and the type thats why you need to loop over the array of fields and construct the template dyamically

<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传递到此动态表单输入

I recommend you create custom components that implements ControlValueAccessor interface (the interface that help you create custom reactive forms) and pass the object field to this dynamic form input

那么如何构建反应形式dynamicForm

so how to build the reactive form dynamicForm

该想法与模板相同:

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

a loop over all the field and set the name of the object and declare the form control values, use the FormBuilder class to help you construct the form

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

let assume field.label is a id of your form field

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是我用来设置表单默认值的示例,我现在不是您的数据的真实结构

field.value is a example I use to set up the default value to the form, I don't now your real structure of your data

这是您可以遵循的方法

更新为新代码

您可以开始改进ngOnInit上的代码 您只会在后端的响应到达后才接收数据,因此您的代码应如下所示:

you can start improving the code on ngOnInit you only going to receive your data once the response from the backend has arrive so your code should look like this

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)
    });


}

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

otherwise the dynamic form never is going to be initialized

这篇关于Angular5通过从数据库获取字段名称和选项来创建表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆