【问题标题】:Angular dynamic formControlName generate with fromGroup使用 formGroup 生成角度动态 formControlName
【发布时间】:2019-07-28 08:25:48
【问题描述】:

我创建了一个由 JSON 数组组成的表单,据此,我正在生成 Validation、formControlName 并通过 formGroup 生成输出。

this.ELEMENT_DATA_UPDATE = [
  {
        first_name : 'abc',
        last_name : 'xyz',
        phone : 8888888888
  }
];

在这里,我使用的是 Angular 材料,因此将此键值对转换为另一个由

组成的数组
{"key" : "first_name" , "value" : "abc" , "name" : "First name :"}

这是输入 JSON 数组固定的时候。但是我的项目包含大规模的数据操作,其中输入的 JSON 数组内容会发生多次变化。生成 UI 模块没有问题,但是当我尝试将 Validation 和 forms 模块应用于这个动态生成的内容时,整个流程崩溃了,

这是我的代码

var jsonArray : any = [{}];

export class UpdateContactFieldDialog {

  matcher = new MyErrorStateMatcher();

  updateForm: FormGroup;

  formString : string = null;
  ELEMENT_DATA_UPDATE : any[] = [];
  keyArray : any[] = [];

  myJobFunctionControl = new FormControl();
    optionsJobFunction: string[] = ['Operations', 'Production', 'Manufacturing'];

  myTitleControl = new FormControl();
    optionsTitle: string[] = ['HR', 'Developer', 'Tester', 'MD', 'CEO', 'Director'];



  constructor(private formBuilder: FormBuilder,private dialogRef: MatDialogRef<AddContactFieldDialog> ) { 

  }

  ngOnInit() {


    //dumy randomly geneated fields
    this.ELEMENT_DATA_UPDATE = [
      {
            first_name : 'abc',
            last_name : 'xyz',
            job_function : 'Production',
            title : 'Developer',
            email : 'abc@abx.com',
            phone : 7945612304
      }
    ];

    for (let obj of this.ELEMENT_DATA_UPDATE) {

        console.log("object length:", this.ELEMENT_DATA_UPDATE.length);
        for (let key in obj) {
            this.keyArray.push({'key' : key , 'value' : obj[key] , 'name': (key.charAt(0).toUpperCase() + key.substr(1).toLowerCase()).replace(/_/g, ' ')});
        }
        break;
    }
    console.log(this.keyArray);
    console.log(this.ELEMENT_DATA_UPDATE[0]);


      for(let formModule of this.keyArray){
       var keyData = formModule.key;
       
        if(this.formString != null && keyData == 'email' || keyData.includes('mail')){
            this.formString = this.formString +''+keyData+':[this.ELEMENT_DATA_UPDATE[0].'+keyData +',[Validators.required,Validators.email]], ';  
        }
        else
          if(this.formString != null && keyData == 'phone' || keyData.includes('number')  || keyData.includes('no') || keyData.includes('num')  ){
            this.formString = this.formString +''+keyData+':[this.ELEMENT_DATA_UPDATE[0].'+keyData +',[Validators.required,Validators.minLength(10),Validators.maxLength(10),Validators.pattern("[0-9]*")]], ';  
        }
        else
        if(this.formString == null && keyData != 'email' && keyData != 'phone'){
          this.formString = ''+keyData+':[this.ELEMENT_DATA_UPDATE[0].'+keyData +',Validators.required], '; 
        }
        else{
            this.formString = this.formString + ''+keyData+':[this.ELEMENT_DATA_UPDATE[0].'+keyData +',Validators.required], ';  
        }

      }
      console.log(this.formString);

        jsonArray = (this.formString);
    this.updateForm = this.formBuilder.group(jsonArray);
         
  }

  // convenience getter for easy access to form fields
  get f() { return this.updateForm.controls; }

  submitContact() {
      this.submitted = true;

      // stop here if form is invalid
      if (this.updateForm.valid) {
        // alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.updateForm.value))
        console.log(this.updateForm.value);
        this.dialogRef.close();
      }
      else{
        return;      
      }
  }

}

我的代码正在生成以下代码作为字符串

first_name: ['', Validators.required],
last_name: ['', Validators.required],
job_function: ['', [Validators.required]],
title: ['', [Validators.required]],
email: ['', [Validators.required, Validators.email]],
phone : ['',[Validators.required, Validators.minLength(10), Validators.maxLength(10),  Validators.pattern('[0-9 ]*')]]

我希望在 formGroup 中使用它,这样我就可以动态生成 formControls ,为它们分配验证和值。

updateForm = this.formBuilder.group(jsonArray);

【问题讨论】:

  • 不生成字符串,创建一个空的 FormGroup (myform=new FormGroup()) 并为每个 keyArray 使用 myForm.addcontrol (name,...) angular.io/api/forms/FormGroup#addcontrol
  • 你能详细说明一下吗?因为我试过这样做。但你的概念可能不同。假设我有 5 个文档,我将从其中获取 5 个单独的密钥,并且需要对这 5 个密钥应用验证并动态使用 for。那么我应该如何用你的逻辑来做到这一点? @Eliseo

标签: json angular html dynamic


【解决方案1】:

补充我的评论,注意:您需要添加验证器(我在您的代码中看不到它们)

this.updateForm=new FormGroup({}) //<--create the formGroup
for(let formModule of this.keyArray){
    this.updateForm.addcontrol(formModule.key,new FormControl(formModule.Value))
}

此外,如果我们在 keyArray 中的对象是这样的

{ "key" : "key_name" , 
   "value" : "value" , 
   "name" : "Key name" ,
   validators:[Validators.required, Validators.email]
}

我们可以改进我们的循环

for(let formModule of this.keyArray){
    this.updateForm.addcontrol(formModule.key,
          new FormControl(formModule.Value,formModule.validators))
}

好吧,如果我们的对象很难像我展示的那样来自服务,但我们的服务可能会为我们服务对象,例如:

{ "key" : "key_name" , 
   "value" : "value" , 
   "name" : "Key name" ,
   validators:[{type:"required"},{type="min",args:3}]
}

在循环之前我们可以使用

this.keyArray.forEach(x=>
{
   if (x.validators)
   {
      conts validators=[];
      validators.forEach(v=>{
          switch (v.type)
          {
               case "required":
                   validators.push(Validators.required);
                   break;
               case "min":
                   validators.push(Validators.min(v.arg);
                   break;
               ...
          }
      })
      x.validators=validators;
   }
}

关于显示错误我们必须考虑到我们在表单中的控件是

updateForm.get(keyArray.key)

所以,例如

<div class="col-lg-6" *ngFor="let keyArray of keyArray"> 
   <mat-form-field> 
        <input type="text" [formControlName]="keyArray.key" matInput 
            [placeholder]="keyArray.name" 
            [ngClass]="{ 'is-invalid': submitted && updateForm.get(keyArray.key).errors }" 
            autocomplete="off" />
         <mat-error *ngIf="submitted && updateForm.get(keyArray.key).hasError('required')">
             {{keyArray.name}} is <strong>required</strong> 
         </mat-error>
     </mat-form-field>
</div>

【讨论】:

  • 我在新的 FormGroup(..) 中忘记了 {}
  • 谢谢伙计。它对我有用。刚刚将我的验证器添加到您的代码中 this.updateForm.addcontrol(formModule.key,new FormControl(formModule.Value, Validators.required))
  • 它在脚本部分工作得很好,但现在在 的前端和 f.keyArray.key 的 [ngClass] 绑定处生成错误 &lt;div class="col-lg-6" *ngFor="let keyArray of keyArray"&gt; &lt;mat-form-field&gt; &lt;input type="text" [formControlName]="keyArray.key" matInput [placeholder]="keyArray.name" [ngClass]="{ 'is-invalid': submitted &amp;&amp; f.keyArray.key.errors }" autocomplete="off" /&gt;&lt;mat-error *ngIf="submitted &amp;&amp; f.keyArray.key.hasError('required')"&gt; {{keyArray.name}} is &lt;strong&gt;required&lt;/strong&gt; &lt;/mat-error&gt;&lt;/mat-form-field&gt;&lt;/div&gt;为糟糕的格式道歉
  • 不是 f.keyArray.key.errores,是 updateForm.get(keyArray.key).errorsupdateForm.get(keyArray.key).hasError('required') -如果您的表单名为 updateForm-
  • 是的。它是,但我根据在前端(UI)和角度(.ts)传递给 fromControlName 的变量生成随机错误。它适用于 .ts,但会导致 formControlName 处的 UI 部分和 keyArray.key 处的 标记出现问题,其中 keyArray 是由后端生成的数组,其中包含 json 数据为 { "key" : "key_name" , "value" : "value" , "name" : "Key name" }
猜你喜欢
  • 1970-01-01
  • 2021-08-03
  • 2019-06-12
  • 2018-01-06
  • 2022-01-17
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
相关资源
最近更新 更多