How to apply filters to *ngFor?

前端 未结 23 1280
無奈伤痛
無奈伤痛 2020-11-22 03:44

Apparently, Angular 2 will use pipes instead of filters as in Angular1 in conjunction with ng-for to filter results, although the implementation still seems to be vague, wit

相关标签:
23条回答
  • 2020-11-22 04:05

    Another approach I like to use for application specific filters, is to use a custom read-only property on your component which allows you to encapsulate the filtering logic more cleanly than using a custom pipe (IMHO).

    For example, if I want to bind to albumList and filter on searchText:

    searchText: "";
    albumList: Album[] = [];
    
    get filteredAlbumList() {
        if (this.config.searchText && this.config.searchText.length > 1) {
          var lsearchText = this.config.searchText.toLowerCase();
          return this.albumList.filter((a) =>
            a.Title.toLowerCase().includes(lsearchText) ||
            a.Artist.ArtistName.toLowerCase().includes(lsearchText)
          );
        }
        return this.albumList;
    }
    

    To bind in the HTML you can then bind to the read-only property:

    <a class="list-group-item"
           *ngFor="let album of filteredAlbumList">
    </a>
    

    I find for specialized filters that are application specific this works better than a pipe as it keeps the logic related to the filter with the component.

    Pipes work better for globally reusable filters.

    0 讨论(0)
  • 2020-11-22 04:06

    For this requirement, I implement and publish a generic component. See

    https://www.npmjs.com/package/w-ng5

    For use this components, before, install this package with npm:

    npm install w-ng5 --save
    

    After, import module in app.module

    ...
    import { PipesModule } from 'w-ng5';
    

    In the next step, add in declare section of app.module:

    imports: [
      PipesModule,
      ...
    ]
    

    Sample use

    Filtering simple string

    <input type="text"  [(ngModel)]="filtroString">
    <ul>
      <li *ngFor="let s of getStrings() | filter:filtroString">
        {{s}}
      </li>
    </ul>
    

    Filtering complex string - field 'Value' in level 2

    <input type="text"  [(ngModel)]="search">
    <ul>
      <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search}]">
        {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
      </li>
    </ul>
    

    Filtering complex string - middle field - 'Value' in level 1

    <input type="text"  [(ngModel)]="search3">
    <ul>
      <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.valor1', value: search3}]">
        {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
      </li>
    </ul>
    

    Filtering complex array simple - field 'Nome' level 0

    <input type="text"  [(ngModel)]="search2">
    <ul>
      <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'nome', value: search2}]">
        {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
      </li>
    </ul>
    

    Filtering in tree fields - field 'Valor' in level 2 or 'Valor' in level 1 or 'Nome' in level 0

    <input type="text"  [(ngModel)]="search5">
    <ul>
      <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search5}, {field:'n1.valor1', value: search5}, {field:'nome', value: search5}]">
        {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
      </li>
    </ul>
    

    Filtering nonexistent field - 'Valor' in nonexistent level 3

    <input type="text"  [(ngModel)]="search4">
    <ul>
      <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.n3.valor3', value: search4}]">
        {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
      </li>
    </ul>
    

    This component work with infinite attribute level...

    0 讨论(0)
  • 2020-11-22 04:08

    I've created a plunker based off of the answers here and elsewhere.

    Additionally I had to add an @Input, @ViewChild, and ElementRef of the <input> and create and subscribe() to an observable of it.

    Angular2 Search Filter: PLUNKR (UPDATE: plunker no longer works)

    0 讨论(0)
  • 2020-11-22 04:09

    You could also use the following:

    <template ngFor let-item [ngForOf]="itemsList">
        <div *ng-if="conditon(item)"></div>
    </template>
    

    This will only show the div if your items matches the condition

    See the angular documentation for more information If you would also need the index, use the following:

    <template ngFor let-item [ngForOf]="itemsList" let-i="index">
        <div *ng-if="conditon(item, i)"></div>
    </template>
    
    0 讨论(0)
  • 2020-11-22 04:09

    This is my code:

    import {Pipe, PipeTransform, Injectable} from '@angular/core';
    
    @Pipe({
        name: 'filter'
    })
    @Injectable()
    export class FilterPipe implements PipeTransform {
        transform(items: any[], field : string, value): any[] {
          if (!items) return [];
          if (!value || value.length === 0) return items;
          return items.filter(it =>
          it[field] === value);
        }
    }
    

    Sample:

    LIST = [{id:1,name:'abc'},{id:2,name:'cba'}];
    FilterValue = 1;
    
    <span *ngFor="let listItem of LIST | filter : 'id' : FilterValue">
                                  {{listItem .name}}
                              </span>
    
    0 讨论(0)
  • 2020-11-22 04:10

    Here's an example that I created a while back, and blogged about, that includes a working plunk. It provides a filter pipe that can filter any list of objects. You basically just specify the property and value {key:value} within your ngFor specification.

    It's not a lot different from @NateMay's response, except that I explain it in relatively verbose detail.

    In my case, I filtered an unordered list on some text (filterText) the user entered against the "label" property of the objects in my array with this sort of mark-up:

    <ul>
      <li *ngFor="let item of _items | filter:{label: filterText}">{{ item.label }}</li>
    </ul>
    

    https://long2know.com/2016/11/angular2-filter-pipes/

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