提问人:AoiTora 提问时间:9/4/2023 更新时间:9/5/2023 访问量:36
Angular - 动态添加 formControls 仅加载部分数据
Angular - adding dynamically formControls only loads partial data
问:
我正在开发一个 Angular 表单,该表单从服务中获取一些数据,以便用输入填充表单。假设这是一种订购书籍的形式。 用户之前选择了一种类型,该服务返回了适合该类型的书籍列表。因为根据流派的不同,我们并不总是得到相同数量的书籍,所以我必须找到一个转折点,以便生成具有不同 formControlName 的输入。这是我的表格的样子(一个简化版本,所以希望我没有打错字):
myForm.html
<form name="form" [formGroup]="mainForm">
<ng-template ngFor let-book [ngForOf]='datas.books'>
<div>
<span> {{book.title}}</span>
</div>
<div *ngIf="myBookFG.contains('input'+book.isbn)">
<mat-form-field>
<mat-label>Amount to order</mat-label>
<input matInput maxlength='16'formControlName='input{{book.isbn}}' >
</mat-form-field>
</div>
</ng-template>
</form>
myForm.ts(我的表单.ts)
mainForm!: FormGroup;
myBookFG!: FormGroup;
whenSelectedGenreIsChanged(): void {
//[...]
this.bookService.getBooksFromGenre(this.selectedGenre)
.subscribe( (next) => {
if (next){
this.datas = next;
this.changeBookList();
}
});
}
changeBookList(): void{
// Resetting the previous formGroup
this.mainForm.removeControl('myBookFG');
// Then creating a new one populated with the books of the selected genre
this.myBookFG= this.formBuilder.group([]);
for (const book of datas.books){
const inputName = "input" + book.isbn;
this.myBookFG.addControl(inputName, this.formBuilder.control( '', []));
}
this.mainForm.addControl('myBookFG', this.myBookFG);
console.log("Books added : ", this.myBookFG); //Checking if all books controls are imported
}
现在的问题是:这编译得很好,但是,在加载页面时,我最多只能得到列表中显示的几个输入,以及来自浏览器控制台的这个错误:
ERROR Error: Cannot find control with name: 'inputABC123'
at _throwError (forms.mjs:1778:11)
at setUpControl (forms.mjs:1567:13)
at FormGroupDirective.addControl (forms.mjs:5337:9)
at FormControlName._setUpControl (forms.mjs:5893:43)
at FormControlName.ngOnChanges (forms.mjs:5838:18)
at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:1515:14)
at callHook (core.mjs:2568:18)
at callHooks (core.mjs:2527:17)
at executeInitAndCheckHooks (core.mjs:2478:9)
at refreshView (core.mjs:9525:21)
console.log 指示在调用时,控件 inputABC123(以及与书籍数量一样多的输入)确实存在。它显示在错误之前。考虑到页面在脚本有时间将它们设置为控件之前尝试加载数据,我添加了 ,以便除非控件已经存在,否则它不会加载它们,但即使如此,错误仍然存在。此外,与页面中的元素进行交互(单击选择、展开面板等),将向列表中加载更多书籍,而无需重新加载页面。[这意味着,如果我与页面中的足够多的元素进行交互,我最终会得到一个功能表单 - 并不是说我可以要求用户单击按钮 25 次才能看到工作页面]ngIf="myBookFG.contains('input'+book.isbn)"
我怀疑这是一个与异步数据有关的问题,但我似乎无法确定如何解决这个问题。从输入中删除允许正确加载所有数据,但如果没有这个数据,我将无法从每个输入中获取选定的金额来计算要订购的书籍的总和。(我需要将此总和与表格上的不同输入进行比较以进行验证,并获取每本书输入的金额)formControlName='input{{book.isbn}}
答:
这是该解决方案的更新。
原来缺少的只是一个 formGroupName。
<form name="form" [formGroup]="mainForm">
<ng-template ngFor let-book [ngForOf]='datas.books'>
<div formGroupName="myBookFG">
<span> {{book.title}}</span>
</div>
<div *ngIf="myBookFG.contains('input'+book.isbn)">
<mat-form-field>
<mat-label>Amount to order</mat-label>
<input matInput maxlength='16'formControlName='input{{book.isbn}}' >
</mat-form-field>
</div>
</ng-template>
</form>
如果没有该标记,解释器就无法知道它位于我定义的组中,也无法找到该组的内部控件。
评论