我有一个为离子项目创建的嵌套表单,其中我有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。
我真的很感激任何帮助
答案 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);
}
}