角度2反应性嵌套形式

时间:2017-03-02 08:34:46

标签: forms angular

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

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

这是我的编辑脚本:

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的示例:

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

我的问题是我只能使用两种botoxTypes显示的e botoxType。

我真的很感激任何帮助

1 个答案:

答案 0 :(得分:1)

对于任何遇到与我相同问题的人。这就是我改变编辑脚本以在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);
  }

}