Angular - 动态添加 formControls 仅加载部分数据

问题描述 投票:0回答:1

我正在开发一个 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

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 表明调用时,控制输入ABC123(以及与书籍一样多的输入)确实存在。它显示在错误之前。认为页面试图在脚本有时间将数据设置为控件之前加载数据,我添加了 ngIf="myBookFG.contains('input'+book.isbn)",这样除非控件已经存在,否则它不会加载它们,但即使如此,错误仍然存在存在。此外,与页面中的元素交互(单击选择、展开面板等)将在列表中加载更多书籍,而无需重新加载页面。 [这意味着,如果我与页面中足够多的元素进行交互,我最终会得到一个功能表单 - 而不是我可以要求用户单击按钮 25 次才能查看工作页面]

我怀疑这是一个与异步数据有关的问题,但我似乎无法确定如何解决这个问题。从输入中删除 

formControlName='input{{book.isbn}}

可以让所有数据正确加载,但如果没有这个,我将无法从每个输入中获取选定的金额来计算要订购的书籍的总和。 (我需要将此金额与表单上的不同输入进行比较以进行验证,以及获取每本书输入的金额)

    

angular asynchronous angular-dynamic-forms
1个回答
0
投票

事实证明,缺少的只是一个 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>

如果没有这个标签,解释器就无法知道它在我定义的组内,也无法找到该组的内部控件。

© www.soinside.com 2019 - 2024. All rights reserved.