How to apply filters to *ngFor?

前端 未结 23 1114
無奈伤痛
無奈伤痛 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 03:47

    A simple solution that works with Angular 6 for filtering a ngFor, it's the following:

    <span *ngFor="item of itemsList"  >
      <div *ngIf="yourCondition(item)">
        
        your code
        
      </div>
    </span

    Spans are useful because does not inherently represent anything.

    0 讨论(0)
  • 2020-11-22 03:47

    I was finding somethig for make a filter passing an Object, then i can use it like multi-filter:

    i did this Beauty Solution:

    filter.pipe.ts

    import { PipeTransform, Pipe } from '@angular/core';
    
    @Pipe({
      name: 'filterx',
      pure: false
    })
    export class FilterPipe implements PipeTransform {
     transform(items: any, filter: any, isAnd: boolean): any {
      let filterx=JSON.parse(JSON.stringify(filter));
      for (var prop in filterx) {
        if (Object.prototype.hasOwnProperty.call(filterx, prop)) {
           if(filterx[prop]=='')
           {
             delete filterx[prop];
           }
        }
     }
    if (!items || !filterx) {
      return items;
    }
    
    return items.filter(function(obj) {
      return Object.keys(filterx).every(function(c) {
        return obj[c].toLowerCase().indexOf(filterx[c].toLowerCase()) !== -1
      });
      });
      }
    }
    

    component.ts

    slotFilter:any={start:'',practitionerCodeDisplay:'',practitionerName:''};
    

    componet.html

                 <tr>
                    <th class="text-center">  <input type="text" [(ngModel)]="slotFilter.start"></th>
                    <th class="text-center"><input type="text" [(ngModel)]="slotFilter.practitionerCodeDisplay"></th>
                    <th class="text-left"><input type="text" [(ngModel)]="slotFilter.practitionerName"></th>
                    <th></th>
                  </tr>
    
    
     <tbody *ngFor="let item of practionerRoleList | filterx: slotFilter">...
    
    0 讨论(0)
  • 2020-11-22 03:49

    This is your array

    products: any = [
            {
                "name": "John-Cena",
                        },
            {
                "name": "Brock-Lensar",
    
            }
        ];
    

    This is your ngFor loop Filter By :

    <input type="text" [(ngModel)]='filterText' />
        <ul *ngFor='let product of filterProduct'>
          <li>{{product.name }}</li>
        </ul>
    

    There I'm using filterProduct instant of products, because i want to preserve my original data. Here model _filterText is used as a input box.When ever there is any change setter function will call. In setFilterText performProduct is called it will return the result only those who match with the input. I'm using lower case for case insensitive.

    filterProduct = this.products;
    _filterText : string;
        get filterText() : string {
            return this._filterText;
        }
    
        set filterText(value : string) {
            this._filterText = value;
            this.filterProduct = this._filterText ? this.performProduct(this._filterText) : this.products;
    
        } 
    
        performProduct(value : string ) : any {
                value = value.toLocaleLowerCase();
                return this.products.filter(( products : any ) => 
                    products.name.toLocaleLowerCase().indexOf(value) !== -1);
            }
    
    0 讨论(0)
  • 2020-11-22 03:49

    There is a dynamic filter pipe that I use

    Source data:

    items = [{foo: 'hello world'}, {foo: 'lorem ipsum'}, {foo: 'foo bar'}];
    

    In the template you can dinamically set the filter in any object attr:

    <li *ngFor="let item of items | filter:{foo:'bar'}">
    

    The pipe:

      import { Pipe, PipeTransform } from '@angular/core';
    
      @Pipe({
        name: 'filter',
      })
      export class FilterPipe implements PipeTransform {
        transform(items: any[], filter: Record<string, any>): any {
          if (!items || !filter) {
            return items;
          }
    
          const key = Object.keys(filter)[0];
          const value = filter[key];
    
          return items.filter((e) => e[key].indexOf(value) !== -1);
        }
      }
    

    Don't forget to register the pipe in your app.module.ts declarations

    0 讨论(0)
  • 2020-11-22 03:50

    I created the following pipe for getting desired items from a list.

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'filter'
    })
    export class FilterPipe implements PipeTransform {
    
      transform(items: any[], filter: string): any {
        if(!items || !filter) {
          return items;
        }
        // To search values only of "name" variable of your object(item)
        //return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1);
    
        // To search in values of every variable of your object(item)
        return items.filter(item => JSON.stringify(item).toLowerCase().indexOf(filter.toLowerCase()) !== -1);
      }
    
    }
    

    Lowercase conversion is just to match in case insensitive way. You can use it in your view like this:-

    <div>
      <input type="text" placeholder="Search reward" [(ngModel)]="searchTerm">
    </div>
    <div>
      <ul>
        <li *ngFor="let reward of rewardList | filter:searchTerm">
          <div>
            <img [src]="reward.imageUrl"/>
            <p>{{reward.name}}</p>
          </div>
        </li>
      </ul>
    </div>
    
    0 讨论(0)
  • 2020-11-22 03:51

    After some googling, I came across ng2-search-filter. In will take your object and apply the search term against all object properties looking for a match.

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