首页 > 解决方案 > Angular - 从带有过滤器的下拉列表中选择更多选项

问题描述

我在使用 Angular 时遇到问题。我有一个项目的下拉列表(实际上对应于公司的员工),我在其上添加了一个搜索过滤器(参见下面的代码),基于员工姓名/姓氏的第一个字母. 我可以选择更多的一个选项。如果我在过滤后从列表中选择一个或多个项目,它工作正常。但是,如果我想选择与我首先选择的过滤器不匹配的其他附加选项,我必须更改过滤器。但碰巧的是,每次我更改过滤器时,包含所选选项(称为checkedEmployees)的数组都会变为空。因此,似乎不可能同时选择通过使用多个过滤器获得的选项。有解决办法吗?谢谢!
这是我的html:

<mat-form-field appearance="fill" class="p-1rem" *ngIf="filteredEmployeeOptions && filteredEmployeeOptions.length > 0">
        <input matInput type="text" name="search" placeholder="Search" (ngModelChange)="filterItem($event)" [(ngModel)]="filterText">
        <mat-label>{{'SHARED.EMPLOYEE_NAME' | translate}}</mat-label>
        <mat-select [(ngModel)]="checkedEmployees" name="employeeName" required multiple>
          <mat-option [value]="employee" *ngFor="let employee of filteredEmployeeOptions">         
              {{employee.lastName}} {{employee.firstName}}
          </mat-option>    
        </mat-select>
</mat-form-field>

这是打字稿:

filterItem(event){
    if(!event){
      this.filteredEmployeeOptions = this.employeeOptions;
    } // when nothing has typed*/   
    if (typeof event === 'string') {
      this.filteredEmployeeOptions = this.employeeOptions.filter(employee => employee.firstName.toLowerCase()
                                          .startsWith(event.toLowerCase()) || employee.lastName.toLowerCase()
                                          .startsWith(event.toLowerCase()));
    }      
}

标签: angular

解决方案


当您在查询时更改员工范围时,filteredEmployeeOptionsreduce 和checkedEmployeesbase 基于这个新的缩减数组。因此,要保留已选择的员工,您必须将它们存储到这个新数组中。

但为了做到这一点,你需要有一个属性(我假设id)来帮助我们防止重复。

尝试执行以下操作以查看是否有效:

filterItem(event) {
  if(!event)
    this.filteredEmployeeOptions = this.employeeOptions;
  // when nothing has typed*/   
  else if (typeof event === 'string') 
    this.filteredEmployeeOptions = this.employeeOptions
                                    .filter(employee => 
                                        employee.firstName.toLowerCase()
                                        .startsWith(event.toLowerCase()) || employee.lastName.toLowerCase()
                                        .startsWith(event.toLowerCase()))
                                    // now we are keeping the already checkedEmployees
                                    .concat(this.checkedEmployees)
                                    // and then we filter by the id to prevent duplicates
                                    .filter(({ id }, index, newArr) => newArr.findIndex(elm => elm.id === id) === index);
      
}

推荐阅读