Angular material 带有键值管道的自动完成过滤器对象

Angular material Autocomplete filter object with keyvalue pipe

我有个小问题,我有这个:

foo = {
   parent1:[{
              data: "John",
           },
           {
              data: "Adam",
           },
           {
              data: "Eva",
           }],
   parent2:[{
              data: "Ricky",
           }]
}

和我的自动完成:

<input type="text" matInput [formControl]="query" [matAutocomplete]="autoGroup"/>
<mat-autocomplete #autoGroup="matAutocomplete">
  <mat-optgroup *ngFor="let parents of foo | keyvalue" [label]="parents.key">
    <mat-option *ngFor="let data of parents.value"  [value]="data.data">
      {{ data.data }}
    </mat-option>
  </mat-optgroup>
</mat-autocomplete>

我想给它设置一个过滤器 - 我只想按 "data" 过滤,例如。如果我输入 "John" - 它只会保留 John with optgroup "parent1" 我创建了演示:

https://stackblitz.com/edit/angular-syzdzg-ytejbp?file=src%2Fapp%2Fautocomplete-filter-example.html

提前致谢!

我不建议你使用KeyValuePipe pipe because it's impure, it means it would be called and translate you object to a new array every change detection cycle. See Pure and impure pipes section of the docs and this SO

无论如何,将对象转换为数组并在之后进行过滤会更容易。你可以找到filter autocomplete example in the angular material docs。在您的情况下,它看起来像:

...
@Component(...)
export class AutocompleteFilterExample {
  ...

  readonly filteredFoo$ = this.query.valueChanges.pipe(
    map((query = '') => {
      const lowerCaseQuery = query.toLocaleLowerCase().trim();
      return Object.entries(this.foo)
        .map(([parentId, items]) => ([
          parentId,
          items.filter(item => {
            const lowerCaseData = item.data.toLocaleLowerCase();
            return lowerCaseData.includes(lowerCaseQuery);
          })
        ]))
        .filter(([prentId, items]) => items.length);
    })
  );
}
<input type="text" matInput [formControl]="query" [matAutocomplete]="autoGroup"/>
<mat-autocomplete #autoGroup="matAutocomplete">
  <mat-optgroup *ngFor="let parents of filteredFoo$ | async" [label]="parents[0]">
    <mat-option *ngFor="let data of parents[1]"  [value]="data.data">
      {{ data.data }}
    </mat-option>
  </mat-optgroup>
</mat-autocomplete>

StackBlitz