Angular 2反应式嵌套形式 [英] Angular 2 reactive nested form

查看:199
本文介绍了Angular 2反应式嵌套形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个为离子项目创建的嵌套表单,其中我有包含formArray的formGroups,每个formArray本身都有一个或多个formGroups。
保存数据的过程非常好。我可以拥有尽可能多的FormArrays,并拥有尽可能多的FormGroups。

I have a nested form created for an ionic project, in which I have formGroups that contain formArray, and each formArray has one or more formGroups, itself. The process of saving data works great. I can have as many formArrays with as many formGroups as I like.

我的问题是当我试图用保存的数据填充表单。我无法正确添加formArrays中的数据。

My problem is when I am trying to populate the form with a saved data. I cannot add correctly the data inside the formArrays.

这是我的编辑脚本:

This is my edit script:

import { Component } from '@angular/core';
import { FormBuilder, FormControl, FormArray, FormGroup, Validators } from '@angular/forms';
import { NavController, NavParams } from 'ionic-angular';
import { Todos } from '../../providers/todos';
import { HomePage } from '../home/home';
import { Patient } from '../../interfaces/patient.interface';

@Component({
  selector: 'page-edit',
  templateUrl: 'edit.html'
})
export class EditPage {

  patient: any;
  patientDate: any;
  editTodoForm: FormGroup;
  submitted: boolean;
  events: any[] = [];

  constructor(public navCtrl: NavController, public todoService: Todos, public navParams: NavParams, public formBuilder: FormBuilder) {
    this.patient = this.navParams.data;
    this.patientDate = new Date(this.patient.date).toISOString();
    this.editTodoForm = formBuilder.group({
      _id: [this.patient._id],
      _rev: [this.patient._rev],
      firstName: [this.patient.firstName, Validators.compose([Validators.pattern('[a-zA-Z ]*'), Validators.required])],
      date: [this.patientDate],
      botoxes: this.formBuilder.array([]),
      acids: this.formBuilder.array([])
    });
    this.subcribeToFormChanges();
    this.addBotox();
    this.addAcid();

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad EditPage');
    this.editTodoForm.setValue(this.patient);
  }

  initBotox() {
    return this.formBuilder.group({
      botoxDate: [''],
      botoxTypes: this.formBuilder.array([
        this.formBuilder.group({
          botoxType: [''],
          botoxZone: [''],
          botoxUnit: ['']
        })
      ])
    });
  }

  addBotox() {
    const control = <FormArray>this.editTodoForm.controls['botoxes'];
    const botoxCtrl = this.initBotox();
    if(this.patient.botoxes) {
      this.patient.botoxes.forEach(botox => {
        control.push(botoxCtrl);
      })
    } else {
      control.push(botoxCtrl);
    }

  }

  removeBotox(i: number) {
    const control = <FormArray>this.editTodoForm.controls['botoxes'];
    control.removeAt(i);
  }

  initAcid() {
    return this.formBuilder.group({
      acidDate: [''],
      acidTypes: this.formBuilder.array([
        this.formBuilder.group({
          acidType: [''],
          acidZone: [''],
          acidUnit: ['']
        })
      ])
    });
  }

  addAcid() {
    const control = <FormArray>this.editTodoForm.controls['acids'];
    const acidCtrl = this.initAcid();

    control.push(acidCtrl);
  }

  removeAcid(i: number) {
    const control = <FormArray>this.editTodoForm.controls['acids'];
    control.removeAt(i);
  }

  subcribeToFormChanges() {
        const myFormStatusChanges$ = this.editTodoForm.statusChanges;
        const myFormValueChanges$ = this.editTodoForm.valueChanges;

        myFormStatusChanges$.subscribe(x => this.events.push({ event: 'STATUS_CHANGED', object: x }));
        myFormValueChanges$.subscribe(x => this.events.push({ event: 'VALUE_CHANGED', object: x }));
    }

  updateTodo(model: Patient, isValid: boolean) {
    this.submitted = true;
    this.todoService.updateTodo(this.editTodoForm.value);
    this.navCtrl.setRoot(HomePage);
  }

}

这是编辑html:

<ion-header no-border>
  <ion-navbar color="primary">
    <ion-title>Editeaza pacient</ion-title>
  </ion-navbar>
</ion-header>


<ion-content padding>

  <form [formGroup]="editTodoForm" novalidate>
    <div [hidden]="editTodoForm.controls.firstName.valid || (editTodoForm.controls.firstName.pristine && !submitted)" class="error-notification">
      Pacientul trebuie sa aiba cel putin un nume si un prenume
    </div>

    <ion-card>
      <ion-card-header>
        Date personale
      </ion-card-header>
      <ion-list padding>
        <ion-item>
          <ion-label stacked>Prenume pacient</ion-label>
          <ion-input type="text" formControlName="firstName"></ion-input>
        </ion-item>
        <ion-item>
          <ion-label stacked>Dată activitate</ion-label>
          <ion-datetime displayFormat="DD MMMM YYYY" pickerFormat="DD MMMM YYYY" formControlName="date"
          monthNames="ianuaie, februarie, martie, aprilie, mai, iunie, iulie, august, septembrie, octombrie, noiembrie, decembrie"></ion-datetime>
        </ion-item>
      </ion-list>
    </ion-card>

    <ion-card>
      <ion-card-header>
        Tratamente botox
      </ion-card-header>
      <ion-list padding>
        <ion-card formArrayName="botoxes">
          <div *ngFor="let botox of editTodoForm.controls.botoxes.controls; let i=index">
            <p class="card-heading">
              <span>Tratament cu botox {{i + 1}}</span>
              <button ion-button icon-only *ngIf="editTodoForm.controls.botoxes.controls.length > 1" (click)="removeBotox(i)" class="right-button remove-button">
      <ion-icon name="trash"></ion-icon>
    </button>
            </p>
            <div [formGroupName]="i">
              <botoxInputs [group]="editTodoForm.controls.botoxes.controls[i]"></botoxInputs>
            </div>
          </div>
        </ion-card>
        <button (click)="addBotox()" ion-button icon-left>
          <ion-icon name="add"></ion-icon>
          Adauga tratament cu botox
        </button>
      </ion-list>
    </ion-card>

    <ion-card>
      <ion-card-header>
        Tratamente acid hialuronic
      </ion-card-header>
      <ion-list padding>
        <ion-card formArrayName="acids">
          <div *ngFor="let acid of editTodoForm.controls.acids.controls; let i=index">
            <p class="card-heading">
              <span>Tratament cu acid hialuronic {{i + 1}}</span>
              <button ion-button icon-only *ngIf="editTodoForm.controls.acids.controls.length > 1" (click)="removeAcid(i)" class="right-button remove-button">
      <ion-icon name="trash"></ion-icon>
    </button>
            </p>
            <div [formGroupName]="i">
              <acidInputs [group]="editTodoForm.controls.acids.controls[i]"></acidInputs>
            </div>
          </div>
        </ion-card>
        <button (click)="addAcid()" ion-button icon-left>
          <ion-icon name="add"></ion-icon>
          Adauga tratament cu acid hialuronic
        </button>
      </ion-list>
    </ion-card>

    <div padding>
      <button ion-button color="primary" block type="submit" (click)="createPatient(editTodoForm, editTodoForm.valid)">Salveaza date pacient</button>
    </div>


  </form>


</ion-content>

这是保存的JSON的一个示例,我试图添加回表单:

And this is an example of a saved JSON I am trying to add back to the form:

{
    "firstName": "Ionescu Ion",
    "date": "2017-02-01T00:00:00.000Z",
    "botoxes": [{
        "botoxDate": "2017-02-01",
        "botoxTypes": [{
            "botoxType": "Xeomin 100UI",
            "botoxZone": ["Frunte", "Crow feet", "Sprânceană"],
            "botoxUnit": "111"
        }, {
            "botoxType": "Azzalure 50UI",
            "botoxZone": ["Glabelar", "Intersprincenos", "Frunte"],
            "botoxUnit": "222"
        }]
    }],
    "acids": [{
        "acidDate": "2017-02-01",
        "acidTypes": [{
            "acidType": "Juvederm Volift",
            "acidZone": ["Periocular", "Tâmple"],
            "acidUnit": "0.5 ml"
        }]
    }],
    "_id": "0A418E81-CFD0-545B-B8DB-A326CECFC5F1",
    "_rev": "3-f2914e24db5fac42930dba548f418cbd"
}

我的问题是我只能得到e botoxType显示了两种botoxTypes。

My problem is that I can get only on e botoxType displayed of the two botoxTypes.

我真的很感谢任何帮助

I would really appreciate any help

推荐答案

对于和我有同样问题的人。这是我改变编辑脚本以正确设置formArrays的初始值的方式:

For anyone having the same issues as I had. This is how I changed my edit script to set initial values properly on formArrays:

import { Component } from '@angular/core';
import { FormBuilder, FormArray, FormGroup, Validators } from '@angular/forms';
import { NavController, NavParams } from 'ionic-angular';
import { Todos } from '../../providers/todos';
import { HomePage } from '../home/home';
import { Patient } from '../../interfaces/patient.interface';

@Component({
  selector: 'page-edit',
  templateUrl: 'edit.html'
})
export class EditPage {

  patient: any;
  editTodoForm: FormGroup;
  submitted: boolean;
  events: any[] = [];

  constructor(public navCtrl: NavController, public todoService: Todos, public navParams: NavParams, public formBuilder: FormBuilder) {
    this.patient = this.navParams.data;
    this.editTodoForm = formBuilder.group({
      _id: [this.patient._id],
      _rev: [this.patient._rev],
      firstName: ['', Validators.compose([Validators.pattern('[a-zA-Z ]*'), Validators.required])],
      date: [''],
      botoxes: this.formBuilder.array([]),
      acids: this.formBuilder.array([])
    });
    this.subcribeToFormChanges();
    if(this.patient.botoxes.length > 0) {
      this.patient.botoxes.forEach(botox => {
        let btys = botox.botoxTypes.length;
        this.addBotox(btys);
      });
    } else {
      this.addBotox(1);
    }
    if(this.patient.acids.length > 0) {
      this.patient.acids.forEach(acid => {
        let atys = acid.acidTypes.length;
        this.addAcid(atys);
      });
    } else {
      this.addAcid(1);
    }

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad EditPage');
    const value: Patient = this.navParams.data;
    (<FormGroup>this.editTodoForm).patchValue(value, { onlySelf: true });
  }

  initBotox(number) {
    return this.formBuilder.group({
      botoxDate: [''],
      botoxTypes: this.addBotoxTypes(number)
    });
  }

  initBotoxTypes() {
      return this.formBuilder.group({
        botoxType: [''],
        botoxZone: [''],
        botoxUnit: ['']
      });
  }


  addBotoxTypes(number) {
    let bts = new FormArray([]);
    for(let i = 0; i < number; i++) {
      bts.push(this.initBotoxTypes())
    }
    return bts;
  }

  addBotox(number) {
    const control = <FormArray>this.editTodoForm.controls['botoxes'];
    const botoxCtrl = this.initBotox(number);
    control.push(botoxCtrl);
  }

  removeBotox(i: number) {
    const control = <FormArray>this.editTodoForm.controls['botoxes'];
    control.removeAt(i);
  }

  initAcid(number) {
    return this.formBuilder.group({
      acidDate: [''],
      acidTypes: this.addAcidTypes(number)
    });
  }

  initAcidTypes() {
      return this.formBuilder.group({
        acidType: [''],
        acidZone: [''],
        acidUnit: ['']
      });
  }


  addAcidTypes(number) {
    let acs = new FormArray([]);
    for(let i = 0; i < number; i++) {
      acs.push(this.initAcidTypes())
    }
    return acs;
  }

  addAcid(number) {
    const control = <FormArray>this.editTodoForm.controls['acids'];
    const acidCtrl = this.initAcid(number);

    control.push(acidCtrl);
  }

  removeAcid(i: number) {
    const control = <FormArray>this.editTodoForm.controls['acids'];
    control.removeAt(i);
  }

  subcribeToFormChanges() {
        const myFormStatusChanges$ = this.editTodoForm.statusChanges;
        const myFormValueChanges$ = this.editTodoForm.valueChanges;

        myFormStatusChanges$.subscribe(x => this.events.push({ event: 'STATUS_CHANGED', object: x }));
        myFormValueChanges$.subscribe(x => this.events.push({ event: 'VALUE_CHANGED', object: x }));
    }

  updateTodo(model: Patient, isValid: boolean) {
    this.submitted = true;
    this.todoService.updateTodo(this.editTodoForm.value);
    this.navCtrl.setRoot(HomePage);
  }

}

这篇关于Angular 2反应式嵌套形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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