How to filter items inside “ngFor” loop, based on object property string

后端 未结 1 825
庸人自扰
庸人自扰 2021-02-14 00:47

I need to filter items inside an ngFor loop, by changing the category in a drop-down list. Therefore, when a particular category is selected from the list, it shoul

相关标签:
1条回答
  • 2021-02-14 00:54

    Here is a sample pipe:

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
        name: 'matchesCategory'
    })
    export class MathcesCategoryPipe implements PipeTransform {
        transform(items: Array<any>, category: string): Array<any> {
            return items.filter(item => item.category === category);
        }
    }
    

    To use it:

    <li *ngFor="let model; of models | matchesCategory:model.category" (click)="gotoDetail(model)">
    

    ===== for the plunkr example ====

    You need your select changes to reflect in some variable

    First define in your class a member:

    selectedCategory: string;
    

    then update your template:

    <select (change)="selectedCategory = $event.target.value">
       <option *ngFor="let model of models ">{{model.category}}</option>
    </select>
    

    last, use the pipe:

      <li *ngFor="let model; of models | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
    

    ==== comments after seeing the plunker ====

    I noticed you used promise. Angular2 is more rxjs oriented. So the first thing I'd change is in your service, replace:

    getModels(): Promise<Model[]> {
      return Promise.resolve(MODELS);
    }
    

    to:

    getModels(): Observable<Array<Model>> {
      return Promise.resolve(MODELS);
    }
    

    and

    getModels(id: number): Observable<Model> {
      return getModels().map(models => models.find(model.id === id);
    }
    

    then in your ModelsComponent

    models$: Observable<Array<Model>> = svc.getModels();
    uniqueCategories$: Observable<Array<Model>> = this.models$
      .map(models => models.map(model => model.category)
      .map(categories => Array.from(new Set(categories)));
    

    Your options will become:

         <option *ngFor="let category; of uniqueCategories$ | async">{{model.category}}</option>
    

    and your list:

          <li *ngFor="let model; of models$ | async | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
    

    This is a very drafty solution since you have many duplicates and you keep querying the service. Take this as a starting point and query the service only once, then derive specific values from the result you got.

    If you'd like to keep you code, just implement a UniqueValuesPipe, its transform will get a single parameter and filter it to return unique categories using the Array.from(new Set(...)). You will need though to map it to strings (categories) first.

    0 讨论(0)
提交回复
热议问题