首页 > 解决方案 > 使用过滤后的数据进行第二次 mat-autocomplete 更新

问题描述

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

这是我的自动完成功能之一:

                <!-- 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: Observable<string[]>;第二个自动完成是使用它自己的列表filteredClaimedBy: Observable<string[]>;

OnInit 我从服务中获取唯一代码/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]指令视为一种可能使输入更新的方法,但是对于一个人来说,无法确切地弄清楚如何使用它,即使使用它,我也不知道它会使其他自动完成更新他们的当第一个改变时的值,反之亦然。

标签: angulartypescriptangular-materialmat-autocomplete

解决方案


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

首先,在每个进行过滤的输入上,我分别在输入上(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> 

此函数创建一个新数组来保存过滤表中的新可能值,等待一整秒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)));
  }

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


推荐阅读