有没有办法强制Angular表单重新创建它的控件?我的意思是创建新实例?看起来它只在初始加载时创建它们。不确定我是否真的需要它,但这是我的问题:
我有一个"编辑"我需要编辑的项目@Input() set item(editItem)
的控件。我从其父项设置此项,控件应重置表单值。
在表单中,我使用自己的自定义下拉控件,该控件具有可绑定的选项列表。
通常它看起来像这样:
@Component({
template:`
<form [formGroup]="form">
<my-control [items]="items" formControlName="itemId"></app-combobox>
</form>
`
export class EditComponent implements OnInit {
items = [{text: 'Item 1', itemId: 1}, {text: 'Item 2', itemId: 2}];
@Input() set editItem(item) {
//if some logic...
this.items = [{text: 'Item 3', itemId: 3}, {text: 'Item 4', itemId: 4}];
this.initForm(item);
}
constructor(private _fb: FormBuilder) {}
ngOnInit(): void {
this.initForm();
}
initForm(item?) {
this.form = this._fb.group({
// itemId could differ and should be in the items list before binding happens
'itemId': [item ? item.itemId : null]
}
}
和控件:
export class ComboboxComponent implements ControlValueAccessor {
items = [];
@Input() set items(list[]) {
this.items = list;
this.updateValue();
}
// ControlValueAccessor implementation
writeValue(value: any) {
this.updateValue();
}
updateValue() {
// here we try to use a newly updated list (but it's not updated yet!)
}
}
问题是即使我在创建新的formGroup之前设置了一个新的项目列表,表单绑定也会在我的项目列表绑定之前发生。我的下拉控件上的writeValue
之前会调用ControlValueAccessor
界面中的@Input() set items([])
方法。
我可以在setTimeout(() => this.updateValue())
内使用writeValue
,这似乎有所帮助,但我不喜欢这个解决方案。如何在表单绑定之前进行控件属性绑定?在initForm()
无效之前调用超时或强制Angular检测更改。
答案 0 :(得分:3)
我做类似的方法是在ngOnInit中设置表格结构,如下所示:
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: ''
});
然后,当数据发生变化时,我不会改变它。相反,我只是使用以下代码更新表单上的值:
onProductRetrieved(product: IProduct): void {
if (this.productForm) {
this.productForm.reset();
}
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 || []));
}
您可以从@Input设置器中调用它。