简体   繁体   English

Angular 5使用FormArray填充数据

[英]Angular 5 populate data with FormArray

In angular 5 I have made the functionality for add new row and remove row by using formarray. 在angular 5中,我通过使用formarray实现了添加新行和删除行的功能。 Its working fine for now. 现在可以正常工作了。 But lets say I have some data and I want to show them in the rows one by one so lets say I have data for 3 rows so the form should automatically show 3 rows by default with all the values populated in it with add and remove row functionality. 但可以说我有一些数据,我想一一显示在行中,所以可以说我有3行的数据,因此该表单默认情况下应自动显示3行,并在其中添加并添加所有行和删除行的值功能。

This is the code what I have done so far 这是我到目前为止所做的代码

app.component.html looks like this app.component.html看起来像这样

<div class="container col-md-12">
  <h1 class="page-header">Create Event</h1>
  <div class="row show-hide-message">
    <div [ngClass]= "messageClass">{{message}}</div>
  </div>
  <form [formGroup] = "form" (ngSubmit)="onEventSubmit()">
  <fieldset>
    <div class="form-group">
      <label for="eventname">Event Name</label>
      <div class='form-group' [ngClass]="{'has-error': form.controls.eventname.errors && form.controls.eventname.dirty, 
  'has-success': !form.controls.eventname.errors
}">
        <input type="text" class="form-control" autocomplete="off" placeholder="Event Name" formControlName="eventname">
        <ul class="help-block">
          <li *ngIf="(form.controls.eventname.errors?.minlength ) && form.controls.eventname.dirty">Event name should be atleast 5 characters</li>
        </ul>
      </div>
    </div>


    <h4>Package Price</h4>
    <hr>
    <div class="row" formArrayName="sections">
      <div class="col-md-12" *ngFor="let section of getSections(form); let i = index" [formGroupName]="i">
        <div class="form-group col-md-5">
          <label for="packagename">Package Name</label>
          <input type="text" class="form-control" autocomplete="off" placeholder="Package Name" formControlName="packagename"  >
       </div>
        <div class="form-group col-md-2">
          <label for="packageprice">Package Price</label>
          <input type="number" class="form-control" autocomplete="off" placeholder="Package Price" formControlName="packageprice" >
        </div>
        <div class="form-group col-md-2">
          <label for="packagelimit">Max Purchase Limit</label>
          <input type="number" class="form-control" formControlName="packagelimit" autocomplete="off" >
        </div>
        <div class="form-group col-md-1">
          <br/>
          <input type="button" (click)="addPackageRow()" class="btn btn-md btn-success" value="+" name="">
        </div>
        <div class="form-group col-md-1" *ngIf="getSections(form).length > 1">
          <br/>
          <input type="button" (click)="removeSection(i)" class="btn btn-md btn-error" value="-" name="">
        </div>
      </div>
    </div>

    <input [disabled]=!form.valid type="submit" class="btn btn-primary" value="Submit">

    <pre>{{form.value | json}}</pre>

  </fieldset>
</form>
</div>

app.component.ts looks like this app.component.ts看起来像这样

import { Component, OnInit } from '@angular/core';
import { FormArray, FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  form :  FormGroup;
  packagesArray: FormArray;

  storageData = [
    {"packagename":"Package One","packageprice":12,"packagelimit":9},
    {"packagename":"Package Two","packageprice":78,"packagelimit":5},
    {"packagename":"Package Three","packageprice":89,"packagelimit":7}
];

  constructor(
    private formBuilder : FormBuilder,
    ) { this.createEventForm() }

  createEventForm() {
    this.form = this.formBuilder.group({
      eventname: ['', Validators.compose([
        Validators.required,
        Validators.minLength(5)
      ])],
      packages: this.packagesArray
    })
  }

  ngOnInit() {
    this.form = new FormGroup({
      eventname: new FormControl(''),
      sections: new FormArray([
        this.initSection(),
      ]),
    });
  }

  initSection() {
    return new FormGroup({
      packagename: new FormControl(''),
      packageprice: new FormControl(''),
      packagelimit: new FormControl('')
    });
  }

  initItemRows() {
        return this.formBuilder.group({
            itemname: ['']
        });
    }

  onEventSubmit() {}

  public addPackageRow() {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection());
  }


  addSection() {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection());
  }

  getSections(form) {
    return form.controls.sections.controls;
  }

  public removeSection(i){
   const control = <FormArray>this.form.get('sections');
   control.removeAt(i);
  }

}

So can someone tell me how to do this? 有人可以告诉我该怎么做吗? Any help and suggestion will be really appreciable. 任何帮助和建议将是非常可贵的。 Thanks 谢谢

I just want to populate data of storageData with the respective rows. 我只想用相应的行填充storageData的数据。

Here is the working demo 这是工作演示

https://stackblitz.com/edit/angular-mh3dpy https://stackblitz.com/edit/angular-mh3dpy

I would go with: 我会去:

this.form = new FormGroup({
  eventname: new FormControl(''),
  sections: new FormArray(this.storageData.map(item => {
    const group = this.initSection();
    group.patchValue(item);
    return group;
  }))
});

Ng-run Example Ng运行示例

Change your ngOnInit :- 更改您的ngOnInit:-

    ngOnInit() {
    this.form = new FormGroup({
      eventname: new FormControl(''),
      sections: new FormArray([
        this.initSection(),
      ]),
    });

    var data;
    for(data in this.storageData){
      console.log(this.storageData[data]);
      var temp = {};
      for(var k in this.storageData[data]){
        //console.log(k);
        temp[k] = new FormControl(this.storageData[data][k]);
      }
      console.log(temp);
      var formGrp = new FormGroup(temp);

      const control = <FormArray>this.form.get('sections');
      control.push(formGrp);
    }
  }

puff, I suggested make a functión that return the formArray 吹,我建议做一个函数,返回formArray

//this.fb is in the constructor private fb:FormBuilder
getSeccion(storageData: any[]): FormArray {
    //create an arr of FormGroup
    //each element of array storageData transform in a FormGroup
    const arr = storageData.map(data => {
        return this.fb.group({
            packagename: [data.packagename,Validators.Required], //<--e.g. if Required
            packageprice: [data.packageprice],
            packagelimit: [data.packagelimit]});
    })
    //return a FormGroup with this array
    return this.fb.array(arr);
}

So, your ngOnInit 因此,您的ngOnInit

ngOnInit() {
    this.form = new FormGroup({
      eventname: new FormControl(''),
      sections: this.getSeccion(this.storageData )
    });

MoreOver, if you has an object MoreOver,如果您有一个对象

mydata={eventname:'myEvent',
        sections:[{packagename:'name1',packageprice:'100',packagelimit:30},
        {..},
        {..}..]

You can use 您可以使用

this.form = new FormGroup({
      eventname: new FormControl(this.myData.eventname),
      sections: this.getSeccion(this.myData.storageData )
    });

Well, normally we get data from database. 好吧,通常我们从数据库中获取数据。 So our ngOnInit can be some like 所以我们的ngOnInit可以像

ngOnInit()
{
    myservice.getData().subscribe((res:any)=>{
          this.data=res  //normally we can save the data in a variable
          this.form = new FormGroup({
              eventname: new FormControl(res.eventname),
              sections: this.getSeccion(res.storageData )
           });
    })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM