0

为了演示该问题,我有一个表格,其中显示了详细信息列表和几个mat-select在选择选项时,此标记选项的“大小”会加载到 td.

桌子

问题是它不会在选择选项的同一行中加载“大小”。我怎么能得到这个?大小显示在 td 中,但按从上到下的顺序排列。

例如,如果没有标记选项并且我从第 3 行中选择了一个选项。此选项的“大小”将加载到第一行,如果我在任何其他行中标记选项,则数据将按照顺序加载行。

我在 stackblitz 中有演示:DemoStackblitz

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">
        <mat-select [formControl]="dataCtrl" placeholder="Select" [compareWith]="compareItems" #singleSelect>
          <mat-option>
            <ngx-mat-select-search [formControl]="dataFilterCtrl"></ngx-mat-select-search>
          </mat-option>
          <mat-option *ngFor="let op of filteredData | async" [value]="op.id" (click)="onSelect(op)"
            [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>

TS

  dataTitles: any = DataTitles;
  dataDetails: any = DataDetails;
  dataCtrl: FormControl = new FormControl();
  dataFilterCtrl: FormControl = new FormControl();
  filteredData: ReplaySubject<any> = new ReplaySubject<any>(1);
  @ViewChild('singleSelect', { static: true }) singleSelect: MatSelect;

  _onDestroy = new Subject<void>();

  ngOnInit() {
    this.dataCtrl.setValue(this.dataDetails[0]);
    this.filteredData.next(this.dataTitles.slice());
    this.dataFilterCtrl.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 = [];
  onSelect(option: any) {
    var objIndex = this.dataTitles.findIndex(x => x.id == option.id);
    if (this.dataTitles[objIndex].title !== 'None') {
      this.dataTitles[objIndex].condition = 1;
    }
    if (this.OptionSelected.length === 0) {
      this.OptionSelected.push({ id: option.id, size: option.size });
    } else {
      let check = this.OptionSelected.map((item: any) => item.id).includes(
        option.id
      );
      if (check === false) {
        this.OptionSelected.push({ id: option.id, size: option.size });
      }
    }
    console.log(this.OptionSelected);
  }
  filterData() {
    if (!this.dataTitles) {
      return;
    }
    let search = this.dataFilterCtrl.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
      )
    );
  }
4

1 回答 1

1

问题

您在OptionSelected调用 onSelect. 这会导致所选行数据与实际显示数据的行不匹配。

伪代码示例:

Select TitleA in Row 4
Push new Data into OptionSelected
OptionSelected[0]?.size displays data in the first row 

解决方案

您已经在此处使用模板变量跟踪当前选定值的值#singleSelect

<mat-select ... #singleSelect>

<mat-select>组件有一个值输入。

@Input()
value: any Value of the select control.

因此,您可以通过简单地使用模板 ref 来显示当前值:

<td>{{singleSelect.value}}</td>

Stackblitz 示例

于 2021-09-07T21:07:37.063 回答