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>
