You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中实现下拉框已选值不可重复选择的方案

实现已选食材不可重复选择的方案

当然可以实现这个需求啦!核心思路就是把已经被选中的食材从下拉选项里过滤掉,只让还没被选过的选项出现在新增行的下拉框中。下面是具体的实现步骤,结合你的代码来调整:

1. 在组件中添加过滤可用食材的方法

首先在你的AppComponent里新增一个方法,用来根据当前表单中已选的食材,过滤出还可以选择的选项。这里假设你的Ingredient接口有唯一标识id(如果没有的话,用name也可以,但要确保名称唯一):

getAvailableIngredients(currentIngredient?: Ingredient): Ingredient[] {
  // 从FormArray中提取所有已选中食材的id
  const selectedIds = (this.form.get('rows') as FormArray).controls
    .map(control => control.get('ingredientData')?.value?.id)
    .filter(id => id != null);

  // 如果是编辑已有行,要排除当前行自己的食材,避免编辑时自己的选项消失
  const excludedIds = currentIngredient 
    ? selectedIds.filter(id => id !== currentIngredient.id) 
    : selectedIds;

  // 返回未被选中的食材列表
  return this.ingredients.filter(ingredient => !excludedIds.includes(ingredient.id));
}

2. 修改模板中的下拉框代码

把原来遍历ingredients的逻辑,换成调用上面的过滤方法,同时传入当前行的已选食材(这样编辑已有行时,当前行的选项不会被过滤掉):

<!-- 假设你遍历FormArray的代码是类似这样的 -->
<div formArrayName="rows" *ngFor="let row of form.get('rows').controls; let i = index">
  <div [formGroupName]="i">
    <div class="col-sm-12">
      <select class="form-control" formControlName="ingredientData">
        <option value="null" hidden>-- Select Ingredient --</option>
        <!-- 调用过滤方法,传入当前行的已选食材 -->
        <option *ngFor="let ingredient of getAvailableIngredients(row.get('ingredientData').value)" 
                [ngValue]="ingredient">
          {{ingredient.name}}
        </option>
      </select>
    </div>
  </div>
</div>

3. 额外注意事项

  • 如果你的Ingredient没有id字段,可以用name替代id进行过滤,但必须保证食材名称是唯一的,否则会出现错误过滤的情况。
  • 当你删除表单行时,被删除的食材会自动重新回到可选列表中,因为selectedIds会随着FormArray的变化自动更新,过滤逻辑会实时生效。
  • 如果遇到变更检测不及时的情况,可以注入ChangeDetectorRef,在添加/删除行后调用cdr.detectChanges()手动触发更新。

内容的提问来源于stack exchange,提问作者Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:31:12