在Angular 2中用数据填充动态表单控件 [英] Populating dynamic form controls with data in Angular 2

查看:60
本文介绍了在Angular 2中用数据填充动态表单控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Angular 2项目中,通过单击按钮可以动态创建输入字段.我正在同样的FormArray的帮助.字段的创建和数据提交工作正常,但是当我尝试使用一些预定义的数据填充字段时,则无法正常工作.我为我的问题制作了一个塞子. https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview 在这里,我想用对象itemData中的数据填充视图上的字段.为便于参考,以下是Angular代码-

I am working on an Angular 2 project where I am creating input fields dynamically on button click. I am taking the help of FormArray for the same. The creation of fields and data submission is working fine but when I am trying to populate the fields with some pre-defined data then it doesn't work. I have created a plunker for my issue. https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview Here I want to populate the fields on the view with the data in the object itemData. For easy reference, following is Angular code -

//our root app component
import { Component, NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `<hr>
              <div>  
                <form [formGroup]="orderForm" (ngSubmit)="OnSubmit(orderForm.value)">
                  <div>
                    <div>
                      <label>Customer Name</label>
                      <input type="text" formControlName="customerName"/>
                      <small *ngIf="IsValidField('customerName')" class="text-danger">
                          Customer Name is required
                      </small>
                    </div>
                    <br/>
                    <div>
                      <label>Customer Email</label>
                      <input type="text" formControlName="email"/>
                      <small *ngIf="IsValidField('email')" class="text-danger">
                          Email is required
                      </small>
                    </div>
                  </div>
                  <br/>
                  <div formArrayName="items" *ngFor="let item of items.controls; let i = index;">
                    <div [formGroupName]="i">
                      <div>
                        <label>Item Name</label>
                        <input type="text" formControlName="name" placeholder="Item name"/>
                        <small *ngIf="IsValidField('name',i)" class="text-danger">
                          Item Name is required
                        </small>
                      </div>
                      <br/>
                      <div>
                        <label>Item Description</label>
                        <input type="text" formControlName="description" placeholder="Item description"/>
                        <small *ngIf="IsValidField('description',i)" class="text-danger">
                          Description is required
                        </small>
                      </div>
                      <br/>
                      <div>
                        <label>Item Price</label>
                        <input type="text" formControlName="price" placeholder="Item price"/>
                        <small *ngIf="IsValidField('price',i)" class="text-danger">
                          Price is required
                        </small>
                      </div>
                      <br/>
                    </div>
                  </div>
                  <button type="submit">Save</button>
                  <button type="button" (click)="addItem()">Add More</button>
                  <button type="button" (click)="loadItems()">Load Items</button>
                </form>
              <div>`,
})

export class App {

  constructor(private formBuilder: FormBuilder) {  }

  public orderForm: FormGroup;
  public formSubmitAttempt: boolean;
  public itemData:any=`{
    "customerName":"Customer 1","email":"abc@xyz.com",
    "items":[{"name":"Item 1","description":"Item 1 Descr","price":"100"},
            {"name":"Item 2","description":"Item 2 Descr","price":"200"},
            {"name":"Item 3","description":"Item 3 Descr","price":"300"}]
  }`;

  ngOnInit() {
    this.orderForm = this.formBuilder.group({
      customerName: ['',[Validators.required]],
      email: ['',[Validators.required]],
      items: this.formBuilder.array([ this.createItem()])
    });
  }

  createItem(): FormGroup {
    return this.formBuilder.group({
      name: ['',[Validators.required,Validators.maxLength(10)]],
      description: '',
      price: ['',[Validators.required,Validators.pattern("[(0-9)]*")]]
    });
  }

  public loadItems(){
    this.orderForm = this.formBuilder.group({
      customerName: [this.itemData.customerName,[Validators.required]],
      email: [this.itemData.email,[Validators.required]],
      items: this.itemData.items
    });
  }

  get items(): FormArray {
    return this.orderForm.get('items') as FormArray;
  };

  addItem(): void {
    this.items.push(this.createItem());
  }

  public OnSubmit(formValue: any) {
    this.formSubmitAttempt = true;
    console.log(JSON.stringify(formValue));
  }

  public IsValidField(field: string, i?:number) {
    if(i!=null) {
      var f = this.orderForm
        .get('items') //retrieve items FormArray
        .get(i.toString()) //retrieve items FormGroup
        .get(field); //retrieve items form field

      return (f.invalid && f.touched) || (f.invalid && this.formSubmitAttempt);
    } else {
      return (this.orderForm.get(field).invalid && this.orderForm.get(field).touched) || (this.orderForm.get(field).invalid && this.formSubmitAttempt);            
    }
  }
}

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

任何帮助将不胜感激.谢谢.

Any help would be appreciated. Thanks.

推荐答案

formArray中的元素必须是formGroups,而不仅仅是对象.

The elements inside a formArray has to be formGroups, not just an object.

在尝试为formArray分配默认值时,通过已经具有的createItems函数运行this.itemData.items.

Run your this.itemData.items through the createItems function you already have when trying to assign default values to your formArray.

public loadItems(){
  this.orderForm.patchValue({
    customerName: this.itemData.customerName,
    email: this.itemData.email
  });

  this.itemData.forEach((item) => {
    (<FormArray>this.orderForm.get('items')).push(this.createItem(item));
  });

}

当数据来自服务时,无需重新创建表单,只需patchValues并相应地更新表单.

No need to recreate the form when data comes from a service, just patchValues and update form accordingly.

PS:您需要修改createItems以获取一些输入数据并返回带有数据的formGroup.

PS: you need to modify createItems to take some input data and return the formGroup with data.

这篇关于在Angular 2中用数据填充动态表单控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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