以 master-detail reactive angular 2 形式添加动态行
Add dynamic row in a master-detail reactive angular 2 form
我需要创建一个能够动态添加详细信息行的主从表单。当我必须加载数据时,问题出现在编辑模式下。实际上,当我通过 formbuilder 添加 formgroups 时,我仍然不知道有多少详细信息("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);
}
}
使用 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。
希望对您有所帮助。
我需要创建一个能够动态添加详细信息行的主从表单。当我必须加载数据时,问题出现在编辑模式下。实际上,当我通过 formbuilder 添加 formgroups 时,我仍然不知道有多少详细信息("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);
}
}
使用 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。
希望对您有所帮助。