Добавьте динамическую строку в форму "Реактивная угловая форма 2"
Мне нужно создать форму master-detail, которая имеет возможность динамически добавлять ряды деталей. Проблема возникает в режиме редактирования, когда мне нужно загрузить данные. На практике, когда я добавляю группы форм через formbuilder, я все еще не знаю, сколько деталей ("Recapiti") будет возвращено мне из Web API ... Есть ли решение для этого?
.....
@Component({
selector: 'formutenti',
templateUrl: './formutenti.component.html',
//styleUrls: ['./formutenti.component.css']
})
export class FormUtentiComponent implements OnInit, AfterViewInit {
complexForm: FormGroup;
submitted: boolean;
recapiti: Recapito[];
myGroupName = ['Recapiti'];
ngOnInit() {
this.complexForm = this.fb.group({
nome: ['', Validators.compose([Validators.required, Validators.maxLength(20)])],
cognome: ['', Validators.compose([Validators.required, Validators.maxLength(20)])],
myArray: this.fb.array([this.createItems(this.recapiti) //<==this.recapiti is undefined
])
});
if (this.data) {
this.utentiService.getUtente(this.data)
.subscribe(data => {
(<FormControl>this.complexForm.controls['nome']).setValue(data['Nome'], { onlySelf: true });
(<FormControl>this.complexForm.controls['cognome']).setValue(data['Cognome'], { onlySelf: true });
this.recapiti = data['Recapiti'];
});
}
}
constructor(private fb: FormBuilder, private utentiService: UtentiService, private sharedService: SharedService, private notificationService: NotificationsService) {
}
createItems(recapiti: Recapito[]): FormGroup[] {
let formGroups: FormGroup[];
if (this.complexForm) {
const control = <FormArray>this.complexForm.controls['myArray'];
for (var _i = 0; _i < recapiti.length; _i++) {
formGroups.push(this.fb.group({
[recapiti[_i].IDrecapito]: this.fb.group({
name: [recapiti[_i].IDrecapito],
indirizzo: [''],
telefono: [''],
email: [''],
})
}))
}
}
return formGroups;
}
initArray(nameObj: any) {
return this.fb.group({
[nameObj]: this.fb.group({
name: [nameObj],
indirizzo: [''],
telefono: [''],
email: [''],
})
})
}
addArray(newName: string) {
const control = <FormArray>this.complexForm.controls['myArray'];
this.myGroupName.push(newName);
control.push(this.initArray(newName));
(<HTMLInputElement>document.getElementById('newName')).value = '';
}
removeDataKey(i: number) {
const control = <FormArray>this.complexForm.controls['myArray'];
control.removeAt(i);
this.myGroupName.splice(i, 1);
}
}
1 ответ
Использование FormArray является правильным решением. У вас просто есть проблема с порядком исполнения в вашем приложении.
Если вы будете следовать своему коду, вы увидите, что вы инициализируете свою FormGroup своими данными до того, как получите их.
В моем приложении код выглядит примерно так:
ngOnInit(): void {
this.productForm = this.fb.group({
productName: ['', [Validators.required,
Validators.minLength(3),
Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
});
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
}
onProductRetrieved(product: IProduct): void {
this.product = product;
// Update the data on the form
this.productForm.patchValue({
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
});
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}
Обратите внимание, что это в onProductRetrieved
После получения данных метод заполняет FormArray.
Надеюсь это поможет.