angular - Kako primijeniti filtre na *ngFor?


Očito, Angular 2 će koristiti pipeove umjesto filtera kao u Angular1 u kombinaciji s ng-for za filtriranje rezultata, iako implementacija još uvijek izgleda nejasno, bez jasne dokumentacije.

Naime, ono što pokušavam postići može se promatrati iz sljedeće perspektive

<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>

Kako to implementirati pomoću cijevi?

Odgovor #1

U osnovi, napišete pipe koju zatim možete koristiti u *ngFor direktivi.

U vašoj komponenti:

filterargs = {title: 'hello'};
items = [{title: 'hello world'}, {title: 'hello kitty'}, {title: 'foo bar'}];

U svom predlošku možete proslijediti niz, broj ili objekt svojoj pipe kako biste ga koristili za filtriranje:

<li *ngFor="let item of items | myfilter:filterargs">

U tvojoj cijevi:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'myfilter',
    pure: false
})
export class MyFilterPipe implements PipeTransform {
    transform(items: any[], filter: Object): any {
        if (!items || !filter) {
            return items;
        }
        // filter items array, items which match and return true will be
        // kept, false will be filtered out
        return items.filter(item => item.title.indexOf(filter.title) !== -1);
    }
}

Ne zaboravite registrirati svoj pipe u app.module.ts; više nije potrebno registrirati pipeove u svom @Component

import { MyFilterPipe } from './shared/pipes/my-filter.pipe';

@NgModule({
    imports: [
        ..
    ],
    declarations: [
        MyFilterPipe,
    ],
    providers: [
        ..
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

Evo Plunker-a koji prikazuje korištenje prilagođenog filter pipe-a i ugrađenog slice pipe-a za ograničavanje rezultata.

Molimo imajte na umu (kako su mnogi komentatori istaknuli) da postoji razlog zašto u Angularu nema ugrađenih filter cijevi.

Odgovor #2

Mnogi od vas imaju odlične pristupe, ali cilj ovdje je biti generički i definirati nizovnu pipe koja je izuzetno ponovno upotrebljiva u svim slučajevima u vezi s *ngFor.

callback.pipe.ts (ne zaboravite ovo dodati u niz deklaracija vašeg modula)

import { PipeTransform, Pipe } from '@angular/core';

@Pipe({
    name: 'callback',
    pure: false
})
export class CallbackPipe implements PipeTransform {
    transform(items: any[], callback: (item: any) => boolean): any {
        if (!items || !callback) {
            return items;
        }
        return items.filter(item => callback(item));
    }
}

Zatim u vašoj komponenti trebate implementirati metodu sa sljedećim potpisom (item: any) => boolean, u mom slučaju, na primjer, nazvao sam je filterUser, koja filtrira korisnike čija je dob veća od 18 godina.

Vaša komponenta

@Component({
  ....
})
export class UsersComponent {
  filterUser(user: IUser) {
    return !user.age >= 18
  }
}

I na kraju, ali ne najmanje važno, vaš html kod će izgledati ovako:

Vaš HTML

<li *ngFor="let user of users | callback: filterUser">{{user.name}}</li>

Kao što možete vidjeti, ovaj Pipe je prilično generički za sve stavke slične poljima koje je potrebno filtrirati putem callback funkcije. U mom slučaju, pokazao se vrlo korisnim za scenarije slične *ngFor.

Nadam se da ovo pomaže!!!

codematrix

Odgovor #3

Ovo sam implementirao bez korištenja pipe.

component.html

<div *ngFor="let item of filter(itemsList)">

komponenta.ts

@Component({
....
})
export class YourComponent {
  filter(itemList: yourItemType[]): yourItemType[] {
    let result: yourItemType[] = [];
    //your filter logic here
    ...
    ...
    return result;
  }
}

Odgovor #4

Pojednostavljeni način (Koristi se samo na malim nizovima zbog problema s izvedbom. U velikim nizovima morate filtar napraviti ručno putem koda):

Pogledajte: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

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

Upotreba :

<li *ngFor="let it of its | filter : 'name' : 'value or variable'">{{it}}</li>

Ako koristite varijablu kao drugi argument, nemojte koristiti navodnike.

Odgovor #5

Nisam siguran kada je stiglo, ali već su napravili odvajačku cijev koja će to učiniti. Također je dobro dokumentirano.

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html

<p *ngFor="let feature of content?.keyFeatures | slice:1:5">
   {{ feature.description }}
</p>

Odgovor #6

Jednostavno rješenje koje funkcionira s Angular 6 za filtriranje ngFor, je sljedeće:

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

Opsezi su korisni jer sami po sebi ne predstavljaju ništa.

Odgovor #7

Također možete koristiti sljedeće:

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

Ovo će prikazati div samo ako vaši predmeti zadovoljavaju uvjet

Pogledajte Angular dokumentaciju za više informacija. Ako biste također trebali indeks, koristite sljedeće:

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

Povezani članci