Angular FormGroup 控件 属性 删除控件时未更新

Angular FormGroup controls property not updated when removing controls

我有一个接受 angular FormGroup 的自定义验证器指令。 controls 属性 主要按预期进行更新,但似乎很难从 FormGroup 中删除控件。这是我第一次使用 FormGroup 所以我不知道我是否实施不正确。

我页面的基本结构是用户可以从下拉列表中 select 多个值,并将它们添加到包含输入元素的 table 中。此 table 中的所有内容(即每个 selected 值一行)都在同一个 FormGroup 中。如果我向 table 添加 3 行,则 group.controls(正确)包含 name0name1name2。但是,如果我然后删除第 2 个然后第 3 个 select 离子,则 group.controls 包含 name0(正确)和 name2(不正确)。

这是表格的基本结构:

<form #modelsForm="ngForm">

    <div class="form-group" ngModelGroup="testModelGroup" #componentModelsFormGroup="ngModelGroup" [appFnValidate]="testValidator">
        <ng-select [items]="models" bindLabel="name" name="models" #modelSelection="ngModel" [(ngModel)]="selectedModels" (add)="selectModel($event)" (remove)="deselectModel($event)" (clear)="deselectAll()">
    </ng-select>

    <table class="table table-striped table-condensed table-hover table-bordered text-nowrap no-margin">
        <thead>
            <tr>
                <th>Model</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let componentModel of component.componentModels; let rowNo = index">
                <td>
                    {{componentModel.modelName}}
                </td>
                <td>
                    <input class="form-control" required #componentModelNameValue="ngModel" [name]="'name' + rowNo" [(ngModel)]="componentModel.name" />
                </td>
            </tr>
        </tbody>
    </table>

  </div>

</form>

[appFnValidate]="testValidator" 代码当前仅注销到控制 FormGroup 包含的控制台。

我做了一个允许复制的 stackblitz。如果您打开开发控制台,您将能够看到来自验证器的日志记录。 https://stackblitz.com/edit/angular-form-group-not-updating

有什么想法可以让 FormGroup controls 属性 在从组中删除控件时正确更新吗?

我在完成问题的格式化时意识到了这个错误的根本原因,所以我想我还是 post 它希望它能在将来对其他人有所帮助!

此问题是由 table 中输入控件的名称引起的,其设置如下:[name]="'name' + rowNo" 其中 rowNo 来自 *ngFor="let componentModel of component.componentModels; let rowNo = index"

但是,删除行时,除非它们是最后一行,否则删除会更改其他行的索引。这似乎阻止 angular 正确跟踪所有内容(可能是因为名称被重用 - 即如果我删除名为 name0 的控件,那么另一个控件将重命名为 name0)。

修复非常简单,只需为 table 中的每一行使用更好的唯一标识符!我使用 componentModel.modelId 因为我知道这在我的场景中是独一无二的。这是唯一需要更改的代码。 tr 标签因此变成:

<tr *ngFor="let componentModel of component.componentModels">
    <td>
        {{componentModel.modelName}}
    </td>
    <td>
        <input class="form-control" required #componentModelNameValue="ngModel" [name]="'name' + componentModel.modelId" [(ngModel)]="componentModel.name" />
    </td>
</tr>