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

时间:2017-10-09 15:21:29

标签: angular angular2-forms

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

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

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

2 个答案:

答案 0 :(得分:0)

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

在尝试为formArray指定默认值时,通过您已有的createItems函数运行:load_file set FILECONTENTS=? sqlplus -S %DB_USER%/%DB_PASSWORD%@%DB_SID% @insert_xml_into_db.sql %1 %FILECONTENTS%

this.itemData.items

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

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

答案 1 :(得分:0)

问题在于你的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]
      });
}

希望它有所帮助:)