使用 Angular 中的数据填充动态表单控件 2

Populating dynamic form controls with data in Angular 2

我正在做一个 Angular 2 项目,我在点击按钮时动态创建输入字段。为此,我正在借助 FormArray。字段的创建和数据提交工作正常,但是当我尝试用一​​些预定义的数据填充字段时,它不起作用。我为我的问题创建了一个 plunker。 https://plnkr.co/edit/PCFD43GK91zo2ivQ9lf7?p=preview 在这里,我想用对象 itemData 中的数据填充视图上的字段。为了便于参考,以下是Angular代码-

//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 {}

如有任何帮助,我们将不胜感激。谢谢

formArray 中的元素必须是 formGroups,而不仅仅是一个对象。

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

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

}

当数据来自服务时无需重新创建表单,只需修补值并相应地更新表单。

PS:您需要修改 createItems 以获取一些输入数据和 return 带有数据的 formGroup。

问题出在您的 itemData 定义中,尝试删除 ` 来定义对象:

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"}]
};

并在您的 loadItems 方法中添加括号以分配 items 的值:

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

希望对您有所帮助:)