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

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

问题描述

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

//我们的根应用组件从@angular/core"导入 { Component, NgModule }从'@angular/platform-b​​rowser' 导入 { BrowserModule }import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms';从@angular/forms"导入 { FormsModule, ReactiveFormsModule };@成分({选择器:'我的应用',模板:`<hr><div><form [formGroup]="orderForm" (ngSubmit)="OnSubmit(orderForm.value)"><div><div><label>客户名称</label><input type="text" formControlName="customerName"/><small *ngIf="IsValidField('customerName')" class="text-danger">客户名称为必填项</小>

<br/><div><label>客户电子邮件</label><input type="text" formControlName="email"/><small *ngIf="IsValidField('email')" class="text-danger">电子邮件是必需的</小>

<br/><div formArrayName="items" *ngFor="let item of items.controls; let i = index;"><div [formGroupName]="i"><div><label>项目名称</label><input type="text" formControlName="name" placeholder="项目名称"/><small *ngIf="IsValidField('name',i)" class="text-danger">项目名称为必填项</小>

<br/><div><label>项目描述</label><input type="text" formControlName="description" placeholder="项目描述"/><small *ngIf="IsValidField('description',i)" class="text-danger">需要说明</小>

<br/><div><label>商品价格</label><input type="text" formControlName="price" placeholder="商品价格"/><small *ngIf="IsValidField('price',i)" class="text-danger">价格为必填项</小>

<br/>

<button type="submit">保存</button><button type="button" (click)="addItem()">添加更多</button><button type="button" (click)="loadItems()">加载项目</button></表单><div>`,})出口类应用{构造函数(私有表单构建器:FormBuilder){}公共订单Form:FormGroup;公共表单提交尝试:布尔值;公共项目数据:任何=`{"customerName":"客户 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({客户名称:['',[Validators.required]],电子邮件:['',[Validators.required]],项目:this.formBuilder.array([ this.createItem()])});}createItem(): FormGroup {返回 this.formBuilder.group({名称:['',[Validators.required,Validators.maxLength(10)]],描述: '',价格:['',[Validators.required,Validators.pattern("[(0-9)]*")]]});}公共负载项目(){this.orderForm = this.formBuilder.group({客户名称:[this.itemData.customerName,[Validators.required]],电子邮件:[this.itemData.email,[Validators.required]],项目:this.itemData.items});}获取项目():FormArray {返回 this.orderForm.get('items') 作为 FormArray;};添加项目():无效{this.items.push(this.createItem());}公共 OnSubmit(formValue: any) {this.formSubmitAttempt = true;console.log(JSON.stringify(formValue));}public IsValidField(field: string, i?:number) {如果(我!=空){var f = this.orderForm.get('items')//检索项目FormArray.get(i.toString())//检索项目FormGroup.get(字段);//检索项目表单字段return (f.invalid && f.touched) ||(f.invalid && this.formSubmitAttempt);} 别的 {return (this.orderForm.get(field).invalid && this.orderForm.get(field).touched) ||(this.orderForm.get(field).invalid && this.formSubmitAttempt);}}}@NgModule({进口:[ BrowserModule, FormsModule, ReactiveFormsModule ],声明:[应用程序],引导程序:[应用程序]})导出类 AppModule {}

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

解决方案

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

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

public loadItems(){this.orderForm.patchValue({客户名称:this.itemData.customerName,电子邮件:this.itemData.email});this.itemData.forEach((item) => {(<FormArray>this.orderForm.get('items')).push(this.createItem(item));});}

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

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

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.

解决方案

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

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

}

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

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

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

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆