繁体   English   中英

如何使用来自http请求的数组将动态输入字段添加到角度表单

[英]How to add dynamic input fields to angular form using array from http request

我已经尝试了所有方法并检查了相关的 stackoverflow 问题,但在这里问什么都没有用。 我必须创建 ui 在选择下拉列表时进行 api 调用并以数组的形式接收数据。 基于这个数组,我想在我的表单中添加尽可能多的字段,因为数组中有多少个元素。 我尝试使用 FormArray 但它没有用。 由于我不断收到与找不到指定名称“名称”的控件相关的错误。 我尝试使用使表单控件字段动态化,但仍然遇到相同的错误。

这是我试过的代码。

.ts 文件

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

@Component({
  selector: 'app-calculator',
  templateUrl: './calculator.component.html',
  styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnInit {

  title = 'Formula Calculation Page';
  configUrlProducts = 'http://localhost:3000/data/products';
  configUrlProductFieldsData = 'http://localhost:3000/data/getproductfields/';

  angForm: FormGroup;
  ruleset_data=[];
  ruleset_data_length=0;
  products: any = [];
  selected_product_id;
  syntax_error=false
  show_form=false;
  arr=[{'name':''},{'class':''},{'tree':''}];
  temp;

 //  products=[{"id":1,"name":'Product 1'},{"id":2,"name":'Product 2'},{"id":3,"name":'Product 3'}]
  constructor(private fb: FormBuilder,private http: HttpClient) {
   console.log("inside constructor")
  //  this.createForm();
   // this.fetch_products();
  }
     // convenience getters for easy access to form fields
     get f() { return this.angForm.controls; }
     get t() { return this.f.fields as FormArray; }


 ngOnInit() {
   console.log("inside ngonit");
  this.angForm = this.fb.group({
    fields: new FormArray([])
  });

  for(var i=0;i<3;i++){
    this.temp=this.arr[i];
    this.t.push(this.fb.group({'name':''}))
  }

  // this.arr.forEach(item=>{
  //   this.t.push(this.fb.group(item))
  // })
  console.log(this.angForm)
   this.getProducts();
 }

 getProducts() {
   console.log("inside get products");
   this.products = [];
   this.http.get(this.configUrlProducts).subscribe((res)=>{
     console.log(res);
     this.products = res["data"];
   });
 }


 fetch_ruleset_data(value: string){
   this.selected_product_id=value;
   console.log("inside get rule data");
   this.ruleset_data = [];
   this.http.get(this.configUrlProductFieldsData+value).subscribe((res)=>{
     console.log(res);
     this.ruleset_data = res["data"];

     this.show_form=true;
      console.log(this.angForm);
     this.ruleset_data_length=res["data"].length;
   });
 }

 onSubmit(value){
   console.log(value);
  //  var data=value;
  //  data["no_of_variables"]=this.ruleset_data_length;
  //  data["product_id"]=this.selected_product_id;
  //  // value=value+this.ruleset_data_length;
  //  // var formula=JSON.parse(value);
  //  console.log("final data before sending to api",data);
  //  return this.http.post('http://localhost:3000/formula/addformula', data)
  //  .subscribe((res)=>{
  //    console.log(res);
  //  })
 }

 validateFormula=(c: FormControl)=> {
   console.log(c.value,typeof c.value);
   var data={};
   data['formula']=c.value;
   data["no_of_variables"]=this.ruleset_data_length;
   data["product_id"]=this.selected_product_id;

   return this.http.post('http://localhost:3000/formula/validateformula', data)
   .subscribe((res)=>{
     // console.log("inside validation after api call",res)
     // console.log(res["error"])
     if(res["error"]){
       console.log("inside error block",res);
       this.syntax_error=true;
       // this.angForm.setErrors({ 'invalid': true });
       // return true;

       return {
         validateFormula: {
           valid: true
         }
       }
     }else{
       this.syntax_error=false;
       // this.angForm.setErrors({ 'invalid': false });
       // return true;
       return {
         validateFormula: {
           valid: true
         }
       }
     }
   })

   // let EMAIL_REGEXP;

   // return EMAIL_REGEXP.test(c.value) ? null : {
   //   validateEmail: {
   //     valid: false
   //   }
   // };
 }


 // fetch_ruleset_data(value: string){
 //   console.log(value);
 // }




}

.html 文件

<!-- app.component.html -->

<div class="container">
        <h1>
          Welcome to {{title}}!!
        </h1>

        <select class="custom-select" (change)="fetch_ruleset_data($event.target.value)">
                <option value="" disabled>Choose your product</option>
                <option *ngFor="let product of products; let i = index" [value]="product.id">
                  {{product.name}}
                </option>
        </select>



        <div *ngIf="show_form==true">
        <form [formGroup]="angForm" (ngSubmit)="onSubmit(angForm.value)">
                <div *ngFor="let item of t.controls; let i = index">
                  <div [formGroup]="item">
                    <input [formControlName]='item'>
                  </div>
                </div>
                <button type="submit">Submit</button>
        </form>


        </div>
        <br />

</div>

过去 2 天一直在努力解决这个问题,非常感谢任何帮助。 我是 angular 的新手,目前正在学习它可能是一件简单的事情,但我目前无法弄清楚,需要您的帮助。

我不知道你收到的数据想象一下你收到的数据,你的例子表明有点像

[{'name':''},{'class':''},{'tree':''}];

真的是一个可怕的数据。 它更“自然”收到一些喜欢

[{col:'name',value:''},{col:'class',value:''},{col:'tree',value:''}];

但我 supouse 是另一个问题。 “键”是在收到数据时创建一个 FormGroup 并且(在您的情况下,创建一个带有字段名称的数组)遍历该数组

   this.http.get(this.configUrlProducts).subscribe((res:any[])=>{
     this.formGroup=new FormGroup({}) //<--create a formGroup empty
     this.fields=[] //<--create an array empty
     res.forEach(x=>{
       const key=Object.keys(x)[0]
       const value=x[key]
       this.formGroup.addControl(key,new FormControl(value))
       this.fields.push(key)
     })
   });

所以,你的 .html 可以像

<form [formGroup]="formGroup">
   <div *ngFor="let col of fields">
       <input [formControlName]="col">
   </div>
</form>

如果您收到的数组类似于“我的自然”方式,则函数和 .html 会像

   this.http.get(this.configUrlProducts).subscribe((res:any[])=>{
     this.formGroup=new FormGroup({}) //<--create a formGroup empty
     res.forEach(x=>{
       const key=x.col
       const value=x.value
       this.formGroup.addControl(key,new FormControl(value))
     })
     this.fields=res;
   });

<form [formGroup]="formGroup">
   <div *ngFor="let field of fields">
       <input [formControlName]="field.col">
   </div>
</form>

如果您收到一个包含名称、值、验证器、标签的对象数组,这个想法可以扩展……因为您可以使用,例如 {{field.label}} 来显示标签

如果你收到 ['a','b','c'] 你可以使用

   this.http.get(this.configUrlProducts).subscribe((res:any[])=>{
     this.formGroup=new FormGroup({}) //<--create a formGroup empty
     res.forEach(x=>{
       this.formGroup.addControl(x,new FormControl(''))
     })
     this.fields=res;
   });

<form [formGroup]="formGroup">
   <div *ngFor="let field of fields">
       <input [formControlName]="field">
   </div>
</form>

您可以使用FormArrayFormGroup来获得所需的结果。

一个例子可以在stackblitz看到。

HTML:

<form [formGroup]="myForm">
    <ng-container *ngFor="let group of myForm.controls |keyvalue">

    <div [formGroup]="group.value">        
        <button type="button" (click)="onAddProduct(group.value)">Add Product</button>
        <div formArrayName="productList">
            <div *ngFor="let item of productArray(group.value).controls; let i = index">
                  <label for="">Your row</label>
                  <input [formControlName]="i">
                  <button (click)="removeProduct(group.value,i)">remove</button>
            </div>
        </div> 
    </div>
<pre>
{{myForm?.value|json}}
</pre>
    </ng-container>
</form>

打字稿:

name = 'Angular';
public myForm: FormGroup;

ngOnInit() {
    this.myForm = new FormGroup({});
    for(let item of ['item1']) {
        this.myForm.addControl(item,
            new FormGroup({
                name: new FormControl(),
                productList: new FormArray([])
            })
         )
     }  
  } 

onAddProduct(group:FormGroup) {
    (group.get('productList') as FormArray).push(new FormControl())
}

productArray(group:FormGroup):FormArray
{
    return group.get('productList') as FormArray;
}

removeProduct(group:FormGroup,index:number)
{
    (group.get('productList') as FormArray).removeAt(index)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM