Angular 动态 formArray 找不到控件
Angular dynamic formArray can't find the controls
我在 FormArray 的帮助下构建动态表单时遇到问题,我正在尝试基于包含 Object 描述数据库行的数组构建表单。目标是向用户显示他选择的每一行及其当前值,让用户修改它们并将它们发回。
所以一切都需要模块化,因为我不知道他选择的行数,也不知道 table 的列数,而且我仍然需要能够检索新数据。
我设法做了一些应该有效的事情,但我仍然有错误:
Error : Cannot find control with name: 'XXXXX'
我觉得这可能是一个关于 lifeCycleHook 的故事,html 在 typescript 中设置控件之前以某种方式执行。
我首先创建了一个名为 modifyForm 的 formArray 和一个 formBuilder
modifyForm: FormArray;
constructor private fb: FormBuilder){}
然后在我的 ngOnInit 函数中我创建了一个循环,用正确的控件填充 modifyForm 并填充 HTML 将用于创建用户界面的 externalArray。
打字稿:
ngOnInit() {
let internalObjects = {}
for (let i = 0; i < this.selectedRows.length; i++) {
const row = this.selectedRows[i];
internalObjects = {}
for (let y = 0; y < Object.keys(row).length; y++) {
const key = Object.keys(row)[y];
const value = Object.values(row)[y];
if (key !== "#") {
this.modifyForm.push(this.fb.control(i + key))
internalObjects[key] = value;
}
}
this.externalArray.push(internalObjects)
}
}
}
HTML :
<form [formGroup]="modifyForm">
<div *ngFor="let object of externalArray; let item = index ">
<div *ngFor="let value of object | keyvalue">
<mat-form-field>
<input matInput [formControlName]='item+value.key' [value]='value.value'>
</mat-form-field>
</div>
</div>
</form>
奇怪的是,在 ngOnInit 函数的末尾,我控制台记录了它似乎使用正确值创建的控件,但它仍然说找不到它们。
打字稿循环:
for (const control of this.modifyForm.controls) {
console.log(control.value)
}
结果:
我知道需要消化的内容很多,我已尽力提供尽可能多的信息,希望阅读起来不会太难。我已经找了好几天了,但我仍然被困在这里。感谢任何可以提供帮助的人! :)
您没有正确绑定到表单数组。使用表单组和表单数组,您可以绑定到键。对于表单数组,这是索引。
this.modifyForm.push(this.fb.control(i + key))
这是在表单数组的下一个可用索引处添加值为 i + key
的表单控件。
在您的 HTML 中,您应该绑定到索引而不是值。您不需要手动设置来自表单绑定的 [value]
。
<input matInput [formControlName]='item' />
其中 item
是 *ngFor
中定义的表单数组中的当前索引
绑定到复杂对象
如果您想创建一个包含多个表单控件的数组,您可以设置一个表单组数组,您的 HTML 指令将反映您的表单结构。
const formGroups: FormGroup[] = myArray.map(x => new FormGroup({
prop1: new FormControl(x.prop1),
prop2: new FormControl(x.prop2)
}));
this.form = new FormArray(formGroups);
<form [formGroup]="form">
<div *ngFor="let item of myArray; let i = index"
[formGroupName]="i"> <!-- <<< bind to the ith form array entry -->
<input formControlName="prop1" />
<input formControlName="prop2" />
</div>
</form>
绑定到未知属性
如果您不知道您的对象属性是什么,您可以从您的对象键创建您的表单。
this.form = new FormArray(this.selectedRows.map(row => {
const formGroup = new FormGroup({});
Object.keys(row).forEach(key => { // <-- use Object.keys to iterate the object
formGroup.addControl(key, new FormControl(row[key]));
});
return formGroup;
}));
并从对象键
生成你的HTML
<form [formGroup]="form">
<div *ngFor="let row of selectedRows;let i = index">
<div [formGroupName]="i">
<!-- use the keyvalue pipe to iterate the key/value pairs of the object -->
<span *ngFor="let keyvalue of row | keyvalue">
<input [formControlName]="keyvalue.key" />
</span>
</div>
</div>
</form>
我在 FormArray 的帮助下构建动态表单时遇到问题,我正在尝试基于包含 Object 描述数据库行的数组构建表单。目标是向用户显示他选择的每一行及其当前值,让用户修改它们并将它们发回。
所以一切都需要模块化,因为我不知道他选择的行数,也不知道 table 的列数,而且我仍然需要能够检索新数据。
我设法做了一些应该有效的事情,但我仍然有错误:
Error : Cannot find control with name: 'XXXXX'
我觉得这可能是一个关于 lifeCycleHook 的故事,html 在 typescript 中设置控件之前以某种方式执行。
我首先创建了一个名为 modifyForm 的 formArray 和一个 formBuilder
modifyForm: FormArray;
constructor private fb: FormBuilder){}
然后在我的 ngOnInit 函数中我创建了一个循环,用正确的控件填充 modifyForm 并填充 HTML 将用于创建用户界面的 externalArray。
打字稿:
ngOnInit() {
let internalObjects = {}
for (let i = 0; i < this.selectedRows.length; i++) {
const row = this.selectedRows[i];
internalObjects = {}
for (let y = 0; y < Object.keys(row).length; y++) {
const key = Object.keys(row)[y];
const value = Object.values(row)[y];
if (key !== "#") {
this.modifyForm.push(this.fb.control(i + key))
internalObjects[key] = value;
}
}
this.externalArray.push(internalObjects)
}
}
}
HTML :
<form [formGroup]="modifyForm">
<div *ngFor="let object of externalArray; let item = index ">
<div *ngFor="let value of object | keyvalue">
<mat-form-field>
<input matInput [formControlName]='item+value.key' [value]='value.value'>
</mat-form-field>
</div>
</div>
</form>
奇怪的是,在 ngOnInit 函数的末尾,我控制台记录了它似乎使用正确值创建的控件,但它仍然说找不到它们。
打字稿循环:
for (const control of this.modifyForm.controls) {
console.log(control.value)
}
结果:
我知道需要消化的内容很多,我已尽力提供尽可能多的信息,希望阅读起来不会太难。我已经找了好几天了,但我仍然被困在这里。感谢任何可以提供帮助的人! :)
您没有正确绑定到表单数组。使用表单组和表单数组,您可以绑定到键。对于表单数组,这是索引。
this.modifyForm.push(this.fb.control(i + key))
这是在表单数组的下一个可用索引处添加值为 i + key
的表单控件。
在您的 HTML 中,您应该绑定到索引而不是值。您不需要手动设置来自表单绑定的 [value]
。
<input matInput [formControlName]='item' />
其中 item
是 *ngFor
绑定到复杂对象
如果您想创建一个包含多个表单控件的数组,您可以设置一个表单组数组,您的 HTML 指令将反映您的表单结构。
const formGroups: FormGroup[] = myArray.map(x => new FormGroup({
prop1: new FormControl(x.prop1),
prop2: new FormControl(x.prop2)
}));
this.form = new FormArray(formGroups);
<form [formGroup]="form">
<div *ngFor="let item of myArray; let i = index"
[formGroupName]="i"> <!-- <<< bind to the ith form array entry -->
<input formControlName="prop1" />
<input formControlName="prop2" />
</div>
</form>
绑定到未知属性
如果您不知道您的对象属性是什么,您可以从您的对象键创建您的表单。
this.form = new FormArray(this.selectedRows.map(row => {
const formGroup = new FormGroup({});
Object.keys(row).forEach(key => { // <-- use Object.keys to iterate the object
formGroup.addControl(key, new FormControl(row[key]));
});
return formGroup;
}));
并从对象键
生成你的HTML<form [formGroup]="form">
<div *ngFor="let row of selectedRows;let i = index">
<div [formGroupName]="i">
<!-- use the keyvalue pipe to iterate the key/value pairs of the object -->
<span *ngFor="let keyvalue of row | keyvalue">
<input [formControlName]="keyvalue.key" />
</span>
</div>
</div>
</form>