
angular 模板中多个 `
在 Angular 基于模板驱动表单(Template-driven Forms)的场景中,<form> 内每个带 ngModel 的表单控件(如 <select>、<input>)必须拥有全局唯一的 name 属性。否则,Angular 会将所有同名控件视为同一个逻辑表单控件,导致模型绑定混乱——后渲染的控件会覆盖先渲染控件的 ngModel 绑定值,最终仅最后一个下拉框能正确显示默认选中项。
你代码中的关键问题在于:
<select class="form-select" [(ngModel)]="currentChannel.selectedValue" name="ddd" <!-- ❌ 所有 select 共用同一 name --> >
尽管 *ngFor 为每个下拉框生成了独立 DOM 节点,但 Angular 表单模块仍依据 name 进行控件注册。当多个 name="ddd" 出现在同一 <form> 中时,NgForm 实例内部仅维护一个名为 "ddd" 的 FormControl,后续绑定会不断覆盖前序值,造成“只有最后一个生效”的现象。
✅ 正确做法:为每个 <select> 动态生成唯一 name,推荐结合索引或 ID:
<form #testScript="ngForm">
<div class="channel-container">
<div
class="channel"
*ngFor="let currentChannel of members; let i = index"
>
<select
class="form-select"
[(ngModel)]="currentChannel.selectedValue"
[name]="'channel_' + i" <!-- ✅ 动态唯一 name -->
#selectCtrl="ngModel"
>
<option
*ngFor="let testFormat of currentChannel.options"
[ngValue]="testFormat"
>
{{ testFormat.val }}
</option>
</select>
</div>
</div>
</form>⚠️ 注意事项:
- 不要使用静态字符串(如 name="ddd")作为循环内表单控件的名称;
- 若需在 TS 中访问特定控件,可配合模板引用变量(如 #selectCtrl="ngModel")或通过 @ViewChildren(NgModel) 查询;
- 确保 selectedValue 初始值严格等于 options 数组中某个对象引用([ngValue] 绑定依赖对象引用相等性),你当前赋值 this.members[0].selectedValue = this.members[0].options[1]; 是正确的;
- 如无需表单提交/验证能力,可直接移除 <form> 标签(正如你测试所见),此时 ngModel 退化为纯双向绑定,不再受 name 冲突影响——但这会失去 Angular 表单的校验、状态管理等能力。
? 总结:模板驱动表单的健壮性始于唯一标识。始终为循环生成的 ngModel 控件分配动态且唯一的 name,是避免此类“默认值丢失”问题的根本准则。










