使用过滤后的数据进行第二次 mat-autocomplete 更新

Make second mat-autocomplete update with filtered data

我有一个 Angular Material table 和数据源集,我正在使用 Material Table Filter 来过滤数据。我有几个 material 自动完成而不是常规输入,它们从 table 的唯一值来源填充他们的选项。就其本身而言,这些自动完成功能可以正常工作 - 如果您在其中搜索一个名称,选项会过滤到 table 中可用的内容。问题出现在多个自动完成中,因为我找不到一种方法使第二个自动完成使用当前过滤的数据更新其选项而不显示每个值。它应该只显示当前筛选数据中的选项。

这是我的自动完成之一:

                <!-- Filter by Course Code -->
            <label for="courseCode">Course Code</label>
            <input type="text"
                id="courseCode"
                [matAutocomplete]="auto1"
                [formControl]="filterCourseCodesControl"
                [(ngModel)]="filterEntity.courseCode"
                #filterCourseCode
                >
            <mat-autocomplete #auto1="matAutocomplete" >
            <mat-option [value]="item" *ngFor="let item of filteredCodes | async" [value]="item">
                {{item}}
            </mat-option>
            </mat-autocomplete>

*ngFor 中的 filteredCodes 是一个可观察的:filteredCodes: Observable<string[]>; 并且第二个自动完成使用它自己的列表 filteredClaimedBy: Observable<string[]>;

OnInit 我从服务中获取了一个唯一 codes/claimedBy 的列表,此处使用的是:

    this.filteredCodes = this.filterCourseCodesControl.valueChanges.pipe(
     startWith(''),
     map(value => this._filterCodes(value))
    );

  private _filterCodes(value: string): string[] {
    const filterValue = this._normalizeValue(value);
    return this.uniqueCodes.filter(item => this._normalizeValue(item).includes(filterValue));
  }

我相信这就是一切;第二个自动完成使用与第一个类似的功能,uniqueCodes 更改为 uniqueClaimedBy,等等

我已经将 [displayWith] 指令视为一种可能使输入更新的方法,但是对于一个人来说,无法弄清楚如何使用它,即使使用它,我也不会知道它会让其他自动完成在第一次更改时更新它们的值,反之亦然。

我又一次发现自己在回答自己的问题。这可能不是最干净的方法,但我能够让所有的自动完成将它们自己限制在过滤后的数据 table 中。这是我所做的:

首先,在每个进行过滤的输入上,我分别在输入的 (keyup)(click)mat-option 上添加了一个函数。

      <div>
        <!-- Filter by Course Code -->
        <label for="courseCode">Course Code</label>
        <input type="text"
            name="courseCode"
            id="courseCode"
            [matAutocomplete]="auto1"
            [formControl]="filterCourseCodesControl"
            [(ngModel)]="filterEntity.courseCode"
            (keyup)="updateAutocomplete()"
            >
        <mat-autocomplete #auto1="matAutocomplete" >
        <mat-option (click)="updateAutocomplete()" [value]="item" *ngFor="let item of filteredCodes | async" [value]="item">
            {{item}}
        </mat-option>
        </mat-autocomplete>
    </div> 

此函数创建一个新数组来保存过滤后的 table 中的新可能值,等待整整一秒让 dataSource.filteredData 填充正确的项目,过滤结果数据以唯一,然后调用 updateCodes.

 updateAutocomplete(){
    let newCodes: string[]  = [];

    setTimeout(() => {
      this.dataSource.filteredData.forEach(e => {
        newCodes.push(e.courseCode.toString());
      });

      newCodes = newCodes.filter(this.onlyUnique);
      
      this.updateCodes(newCodes);

      
    }, 1000);
  }

更新代码只是将管道 valueChanges 数据源从唯一项目的完整列表更新为可能值的较短过滤列表。

updateCodes(source){
this.filteredCodes = this.filterCourseCodesControl.
valueChanges.pipe(startWith(''), map(value => this._filterValues(value, source)));
  }

对每个输入执行相同的流程,您所有的自动完成现在都将自己限制为过滤后的数据,而不是完整列表。