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

Angular中选中mat-select选项后如何将size加载到对应行的td

问题根源

  1. 所有行的mat-select共用了同一个dataCtrl、dataFilterCtrl实例,导致不同行的下拉状态互相干扰。
  2. 选中值存储逻辑错误:onSelect方法将选中项按选择顺序push到OptionSelected数组,和行索引没有绑定,页面按行索引i读取OptionSelected[i]时自然无法匹配到对应的行。
  3. @ViewChild('singleSelect')只能匹配到页面第一个下拉实例,无法支持多行动态生成的下拉组件。

改造方案

1. TS代码调整

import { FormArray, FormControl } from '@angular/forms';
// 其他原有导入保持不变

dataTitles: any = DataTitles;
dataDetails: any = DataDetails;
// 替换原有单个control为数组,对应每一行的下拉
dataCtrlArray: FormArray = new FormArray([]);
dataFilterCtrlArray: FormControl[] = [];
filteredData: ReplaySubject<any> = new ReplaySubject<any>(1);
// 移除原有全局的singleSelect ViewChild

_onDestroy = new Subject<void>();

ngOnInit() {
  // 为每一行初始化独立的控制实例
  this.dataDetails.forEach(() => {
    this.dataCtrlArray.push(new FormControl());
    this.dataFilterCtrlArray.push(new FormControl());
  });
  this.filteredData.next(this.dataTitles.slice());
  // 搜索逻辑调整为监听所有搜索控件的变化
  this.dataFilterCtrlArray.forEach(ctrl => {
    ctrl.valueChanges
      .pipe(takeUntil(this._onDestroy))
      .subscribe(() => {
        this.filterData();
      });
  })
}
compareItems(i1: any, i2: any) {
  return i1 && i2 && i1.key === i2.key;
}
ngOnDestroy() {
  this._onDestroy.next();
  this._onDestroy.complete();
}
OptionSelected: any = [];
// 新增入参rowIndex接收当前选中的行索引
onSelect(option: any, rowIndex: number) {
  var objIndex = this.dataTitles.findIndex(x => x.id == option.id);
  if (this.dataTitles[objIndex].title !== 'None') {
    this.dataTitles[objIndex].condition = 1;
  }
  // 直接将选中值写入对应行索引的位置,替换原有push逻辑
  this.OptionSelected[rowIndex] = { id: option.id, size: option.size };
  // 原有去重逻辑如果需要保留,可在此处补充校验其他行是否已选中当前option
  console.log(this.OptionSelected);
}
filterData() {
  if (!this.dataTitles) {
    return;
  }
  // 搜索逻辑保持不变,所有行共用同一份过滤后的选项列表
  let search = this.dataFilterCtrlArray.find(ctrl => ctrl.value)?.value || '';
  if (!search) {
    this.filteredData.next(this.dataTitles.slice());
    return;
  } else {
    search = search.toLowerCase();
  }
  this.filteredData.next(
    this.dataTitles.filter(
      (x: any) => x.title.toLowerCase().indexOf(search) > -1
    )
  );
}

2. HTML代码调整

<table class="table">
  <tr>
    <th>Titles</th>
    <th>Size</th>
    <th>Detail</th>
    <th>Duration</th>
  </tr>
  <tr *ngFor="let row of dataDetails let i = index">
    <td>
      <mat-form-field appearance="outline">
        <!-- 绑定当前行对应的formControl -->
        <mat-select [formControl]="dataCtrlArray.at(i)" placeholder="Select" [compareWith]="compareItems">
          <mat-option>
            <!-- 绑定当前行对应的搜索control -->
            <ngx-mat-select-search [formControl]="dataFilterCtrlArray[i]"></ngx-mat-select-search>
          </mat-option>
          <mat-option *ngFor="let op of filteredData | async" [value]="op.id" (click)="onSelect(op, i)"
            [disabled]="op.condition===1">
            {{op.title}}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </td>
    <td>{{OptionSelected[i]?.size}}</td>
    <td>{{row.detail}}</td>
    <td>{{row.duration}}</td>
  </tr>
</table>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:18:03