Bagaimana cara menerapkan filter ke * ngFor?

278

Rupanya, Angular 2 akan menggunakan pipa bukan filter seperti pada Angular1 bersamaan dengan ng-untuk menyaring hasil, meskipun implementasinya tampaknya masih samar-samar, tanpa dokumentasi yang jelas.

Yaitu apa yang saya coba capai dapat dilihat dari perspektif berikut

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

Bagaimana cara mengimplementasikannya menggunakan pipa?

Khaled
sumber
8
Perhatikan bahwa perubahan pendobrak diperkenalkan di beta 17 untuk ngFor mengenai simbol hash. Cara yang benar adalah:<div *ngFor="let item of itemsList" *ngIf="conditon(item)" ...
Memet Olsen
11
@MemetOlsen komentar dari Gunter di bawah ini: " *ngFordan *ngIfpada elemen yang sama tidak didukung. Anda perlu mengubah ke bentuk eksplisit untuk salah satu dari mereka"
The Red Pea
1
Meskipun menurut OP, itu direkomendasikan untuk TIDAK MENGGUNAKAN PIPA untuk memfilter atau memesan di Angular2 +. Lebih suka memiliki properti kelas dengan nilai yang difilter: angular.io/guide/pipes#appendix-no-filterpipe- atau
orderbypipe

Jawaban:

395

Pada dasarnya, Anda menulis pipa yang kemudian dapat Anda gunakan dalam *ngForarahan.

Di komponen Anda:

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

Di templat Anda, Anda bisa meneruskan string, angka atau objek ke pipa Anda untuk digunakan untuk memfilter:

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

Di pipa Anda:

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);
    }
}

Ingatlah untuk mendaftarkan pipa Anda ke app.module.ts; Anda tidak perlu lagi mendaftar pipa di@Component

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

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

Inilah Plunker yang melakukan demo penggunaan pipa filter khusus dan pipa slice bawaan untuk membatasi hasil.

Harap perhatikan (seperti yang ditunjukkan beberapa komentator) bahwa ada alasan mengapa tidak ada pipa filter bawaan di Angular.

phuc77
sumber
6
Thanx, ini berfungsi sebagaimana dimaksud, tetapi kadang-kadang lebih baik untuk memeriksa apakah array item didefinisikan dan bukan nol, karena Ng2 dapat mencoba menerapkan filter sementara "item" masih belum ditentukan.
timmz
1
Selain itu, saya perlu menambahkan kelas filter ke deklarasi @Component. Like So: @Component ({... pipes: [MyFilterPipe]
Stephen
1
Saya pikir ini juga membutuhkan baris ìf (! Item) ini untuk mengembalikan item; `seandainya array kosong.
Boštjan Pišler
2
Angular mengatakan menggunakan Pipe memiliki masalah kinerja, jadi rekomendasikan untuk membuat filter pada komponen
Sebastián Rojas
3
Saya ingin menyarankan untuk membungkus *ngForparameter dalam tanda kurung, hanya untuk menghindari kebingungan dan menjadikannya "bukti perubahan":<li *ngFor="let item of (items | myfilter:filterargs)">
Tomas
104

Banyak dari Anda memiliki pendekatan hebat, tetapi tujuannya di sini adalah untuk menjadi generik dan mendefinisikan pipa array yang sangat dapat digunakan kembali di semua kasus dalam hubungannya dengan * ngFor.

callback.pipe.ts (jangan lupa menambahkan ini ke array deklarasi modul Anda)

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));
    }
}

Kemudian di komponen Anda, Anda perlu menerapkan metode dengan signuature berikut (item: any) => boolean , dalam kasus saya misalnya, saya menyebutnya filterUser, yang memfilter usia pengguna yang lebih dari 18 tahun.

Komponen Anda

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

Dan yang tak kalah pentingnya, kode html Anda akan terlihat seperti ini:

HTML Anda

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

Seperti yang Anda lihat, Pipa ini cukup umum di semua array seperti item yang perlu disaring melalui panggilan balik. Di mycase, saya menemukan itu sangat berguna untuk * skenario ngFor.

Semoga ini membantu!!!

codematrix

kode5
sumber
4
Saya perhatikan bahwa dalam function filterUser () - atau fungsi yang setara dengan itu - Anda tidak dapat menggunakan "ini" untuk mengakses instance komponen saat ini seperti Anda dapat dengan semua fungsi lainnya di kelas komponen. Saya perlu mengakses objek komponen untuk memeriksa item yang difilter dalam koleksi.
Paul
1
@ Paul, hmm ... itu tidak mungkin. Apakah metode Anda pribadi? Bukan itu yang penting karena privat hanya mengkompilasi konstruk dan tidak diberlakukan saat runtime. Dalam contoh saya, saya menggunakan IUser. Ini mengasumsikan bahwa item dalam koleksi adalah peta yang di-iterasi. Anda dapat mencoba apa saja untuk melihat apakah itu berhasil. Juga, pastikan nama yang diketik sudah benar, case dan all.
kode5
1
saya tidak dapat mengakses variabel komponen menggunakan metode ini
suulisin
10
Untuk menghindari masalah thisyang terdefinisi, Anda dapat menulis metode Anda pada komponen Anda seperti filterUser = (user: IUser) =>daripadafilteruser(user: IUser)
Tom
2
@ Paul Saya tahu ini sudah terlambat untuk membantu Anda, tetapi mungkin membantu orang lain. Alasan Anda kehilangan thispada metode komponen Anda adalah karena metode itu digunakan sebagai panggilan balik dan thiskonteks baru diterapkan. Anda mengalami masalah umum dalam javascript berorientasi objek, tetapi ada solusi lama dan mudah: Anda mengikat metode yang akan digunakan sebagai panggilan balik ke kelas asli. Di konstruktor Anda, tambahkan kode berikut: this.myCallbackFunc = this.myCallbackFunc.bind(this); Itu dia. Anda tidak akan pernah kehilangan thislagi.
Randolpho
36

Cara yang disederhanakan (Digunakan hanya pada array kecil karena masalah kinerja. Dalam array besar Anda harus membuat filter secara manual melalui kode):

Lihat: 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);
    }
}

Pemakaian:

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

Jika Anda menggunakan variabel sebagai argumen kedua, jangan gunakan tanda kutip.

Rodolfo Jorge Nemer Nogueira
sumber
3
Mungkin tambahkan berikut ini untuk menunjukkan cara menggabungkannya dengan ReqExp: return items.filter (item => {return RegExp baru (nilai, "i"). Test (item [bidang])});
Johannes
8
Menurut tim Angular, ini dianggap praktik buruk.
@torazaburo dapatkah Anda merujuk pendapat mereka atau menjelaskan alasannya? Terima kasih
Zymotik
2
Menurut tim Angular, ini kode yang buruk karena lambat dan tidak diperkecil dengan baik. Tim tidak ingin melihat situs web yang lambat karena kode mereka sehingga mereka tidak membangunnya menjadi Angular saat ini. angular.io/docs/ts/latest/guide/…
Zymotik
29

Inilah yang saya terapkan tanpa menggunakan pipa.

component.html

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

komponen.ts

@Component({
....
})
export class YourComponent {
  filter(itemList: yourItemType[]): yourItemType[] {
    let result: yourItemType[] = [];
    //your filter logic here
    ...
    ...
    return result;
  }
}
Thang Le
sumber
16
Saya pikir ini akan menjadi komputasi intensif karena Angular akan mengeksekusi filter setiap kali menjalankan deteksi perubahan. Ini tidak akan skala dengan baik untuk array besar. Sebuah bersih, meskipun lebih kompleks untuk kode, solusi akan membuat itemListsebuah diamati dan menggunakan filter async: let item of itemsList | async. Ketika perubahan terjadi, buat yang terpantau mengeluarkan daftar baru. Dengan cara ini, kode penyaringan hanya dijalankan saat dibutuhkan.
BeetleJuice
1
Jawaban ini seharusnya memiliki skor negatif. Itu buruk, gunakan pipa.
Cétia
19

Saya tidak yakin kapan itu masuk tetapi mereka sudah membuat pipa slice yang akan melakukan itu. Juga didokumentasikan dengan baik.

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>
SpaceBeers
sumber
4
Jika Anda menggunakan Antarmuka trackBy pipa slice harus diterapkan sebelum ;. mis:*ngFor="let feature of content?.keyFeatures | slice:1:5; trackBy feature?.id"
Philip
11

Anda juga dapat menggunakan yang berikut ini:

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

Ini hanya akan menampilkan div jika item Anda sesuai dengan kondisi

Lihat dokumentasi sudut untuk informasi lebih lanjut. Jika Anda juga memerlukan indeks, gunakan yang berikut ini:

<template ngFor let-item [ngForOf]="itemsList" let-i="index">
    <div *ng-if="conditon(item, i)"></div>
</template>
Jeroen
sumber
1
Bukankah ini akan memasukkan template untuk setiap item dalam daftar, bukan hanya daftar yang difilter? Itu bisa menjadi hit kinerja.
Azeroth2b
8

pipa di Angular2 mirip dengan pipa di baris perintah. Output dari masing-masing nilai sebelumnya dimasukkan ke filter setelah pipa yang membuatnya mudah untuk rantai filter juga seperti ini:

<template *ngFor="#item of itemsList">
    <div *ngIf="conditon(item)">{item | filter1 | filter2}</div>
</template>
Ben Glasser
sumber
Maaf jika ini menyesatkan, poin saya di sini adalah variabel itemdari yang *ng-for="#item of itemsList"seharusnya digunakan untuk memfilter hasil *ng-if="conditon(item)". Yang tidak berfungsi dalam contoh ini ..
Khaled
Anda dapat membuat filter kondisi dan melakukan hal yang sama dengan {{item | condition}} kondisi hanya akan kembali itemjika kondisi terpenuhi dan tidak ada nilai jika tidak.
Ben Glasser
@ BenGlasser Saya pikir pipa diterapkan dari kanan ke kiri. Jadi ini akan menerapkan filter2 terlebih dahulu, lalu filter1.
Evan Plaice
12
*ngFordan *ngIfpada elemen yang sama tidak didukung. Anda perlu mengubah ke bentuk eksplisit untuk salah satunya<template ngFor ...>
Günter Zöchbauer
1
@ GünterZöchbauer Butuh waktu setahun, tapi saya sudah memperbarui sintaks untuk mencerminkan perubahan yang Anda sarankan
Ben Glasser
5

Untuk persyaratan ini, saya menerapkan dan menerbitkan komponen generik . Lihat

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

Untuk menggunakan komponen ini, sebelumnya, instal paket ini dengan npm:

npm install w-ng5 --save

Setelah itu, impor modul di app.module

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

Pada langkah selanjutnya, tambahkan bagian menyatakan di app.module:

imports: [
  PipesModule,
  ...
]

Penggunaan sampel

Memfilter string sederhana

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

Memfilter string kompleks - bidang 'Nilai' di 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>

Memfilter string kompleks - bidang tengah - 'Nilai' di 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>

Memfilter array sederhana yang kompleks - bidang '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>

Memfilter di bidang pohon - bidang 'Valor' di level 2 atau 'Valor' di level 1 atau 'Nome' di 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>

Memfilter bidang yang tidak ada - 'Valor' di level 3 yang tidak ada

<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>

Komponen ini berfungsi dengan level atribut ...

Wedson Quintanilha da Silva
sumber
Hai, saya di sini dan saya telah mengikuti semua langkah dan dalam hal ini saya menggunakan ini *ngFor="let inovice of invoices | filter:searchInvoice"dan sedang mencari di daftar saya, tetapi menunjukkan daftar kosong, apakah Anda tahu mengapa?
jecorrales
1
Halo, tolong beri tahu saya apa struktur dan jenis objek yang berisi daftar faktur Anda. Cara Anda menggunakannya hanya boleh diterapkan jika daftar faktur Anda adalah tipe string. Jika Anda ingin mencari berdasarkan nomor faktur (invoice.number), gunakan ini: * ngFor = "biarkan inovice of invoice | filter: {field: number, value: searchInvoice}" . Jika Anda ingin memfilter dengan dua kolom, misalnya, invoice.customer.name, gunakan: * ngFor = "biarkan inovice of invoice | filter: [bidang: angka, nilai: searchInvoice}, {bidang: customer.name, nilai: searchInvoice}] .
Wedson Quintanilha da Silva
4

Solusi sederhana yang berfungsi dengan Angular 6 untuk memfilter ngFor, berikut ini:

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

Rentang berguna karena tidak secara inheren mewakili apa pun.

Michael V
sumber
1
lebih baik daripada <span> adalah menggunakan <ng-container> karena tidak akan menambahkan markup yang tidak perlu yang selain suara html dapat mempengaruhi CSS Anda.
Trevor de Koekkoek
4

Saya tahu ini pertanyaan lama, namun saya pikir mungkin ada gunanya menawarkan solusi lain.

setara dengan AngularJS ini

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

dalam Angular 2+ Anda tidak dapat menggunakan * ngFor dan * ngIf pada elemen yang sama, jadi akan menjadi berikut:

<div *ngFor="let item of itemsList">
     <div *ngIf="conditon(item)">
     </div>
</div>

dan jika Anda tidak dapat menggunakan wadah internal gunakan wadah-ng sebagai gantinya. ng-container berguna ketika Anda ingin menambahkan sekelompok elemen secara kondisional (yaitu menggunakan * ngIf = "foo") dalam aplikasi Anda tetapi tidak ingin membungkusnya dengan elemen lain.

tgralex
sumber
4

Saya telah membuat plunker berdasarkan jawaban di sini dan di tempat lain.

Selain itu saya harus menambahkan @Input, @ViewChild, dan ElementRefdari <input>serta membuat dan subscribe()ke diamati itu.

Filter Pencarian Angular2 : PLUNKR (UPDATE: plunker tidak lagi berfungsi)

Nate May
sumber
3

Pipa akan menjadi pendekatan terbaik. tetapi di bawah satu juga akan berfungsi.

<div *ng-for="#item of itemsList">
  <ng-container *ng-if="conditon(item)">
    // my code
  </ng-container>
</div>
Hardik Patel
sumber
ini dapat merusak hal-hal tertentu. misalnya di dalam mat-form-field
pcnate
2

Ini kode saya:

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);
    }
}

Sampel:

LIST = [{id:1,name:'abc'},{id:2,name:'cba'}];
FilterValue = 1;

<span *ngFor="let listItem of LIST | filter : 'id' : FilterValue">
                              {{listItem .name}}
                          </span>
Pàldi Gergő
sumber
1

Pendekatan lain yang saya suka gunakan untuk aplikasi filter spesifik, adalah dengan menggunakan properti read-only kustom pada komponen Anda yang memungkinkan Anda untuk merangkum logika penyaringan lebih bersih daripada menggunakan pipa kustom (IMHO).

Misalnya, jika saya ingin mengikat albumListdan memfilter 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;
}

Untuk mengikat dalam HTML, Anda kemudian dapat mengikat ke properti hanya-baca:

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

Saya menemukan untuk filter khusus yang spesifik aplikasi ini berfungsi lebih baik daripada pipa karena membuat logika yang terkait dengan filter dengan komponen.

Pipa bekerja lebih baik untuk filter yang dapat digunakan kembali secara global.

Rick Strahl
sumber
1
Bukankah metode ini akan memicu pemeriksaan kotor terus menerus alih-alih menggunakan pendekatan valueChanged?
Léon Pelletier
1

Saya membuat pipa berikut untuk mendapatkan barang yang diinginkan dari daftar.

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);
  }

}

Konversi huruf kecil hanya untuk mencocokkan jika cara tidak sensitif. Anda dapat menggunakannya dalam tampilan seperti ini: -

<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>
Sanchit Tandon
sumber
1

Idealnya Anda harus membuat 2 pipa angual untuk itu. Tetapi Anda bisa melakukan trik ini.

<ng-container *ngFor="item in itemsList">
    <div*ngIf="conditon(item)">{{item}}</div>
</ng-container>
sh977218
sumber
1

Berdasarkan solusi pipa callback yang sangat elegan yang diusulkan di atas, dimungkinkan untuk menggeneralisasikannya sedikit lebih jauh dengan memungkinkan parameter filter tambahan untuk diteruskan. Kami kemudian memiliki:

callback.pipe.ts

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

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

komponen

filterSomething(something: Something, filterArgs: any[]) {
  const firstArg = filterArgs[0];
  const secondArg = filterArgs[1];
  ...
  return <some condition based on something, firstArg, secondArg, etc.>;
}

html

<li *ngFor="let s of somethings | callback : filterSomething : [<whatWillBecomeFirstArg>, <whatWillBecomeSecondArg>, ...]">
  {{s.aProperty}}
</li>
Blablalux
sumber
0

Berikut adalah contoh yang saya buat beberapa waktu lalu, dan di-blog, tentang yang termasuk plunk yang berfungsi. Ini menyediakan pipa filter yang dapat menyaring daftar objek. Anda pada dasarnya hanya menentukan properti dan nilai {key: value} dalam spesifikasi ngFor Anda.

Tidak jauh berbeda dari respons @ NateMay, kecuali saya jelaskan dengan detail yang relatif verbose.

Dalam kasus saya, saya memfilter daftar tidak terurut pada beberapa teks (filterText) yang dimasukkan pengguna terhadap properti "label" objek dalam array saya dengan semacam mark-up:

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

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

tahu lama
sumber
0

Langkah pertama Anda membuat Filter menggunakan @Pipefile component.ts Anda:

your.component.ts

import { Component, Pipe, PipeTransform, Injectable } from '@angular/core';
import { Person} from "yourPath";

@Pipe({
  name: 'searchfilter'
})
@Injectable()
export class SearchFilterPipe implements PipeTransform {
  transform(items: Person[], value: string): any[] {
    if (!items || !value) {
      return items;
    }
    console.log("your search token = "+value);
    return items.filter(e => e.firstName.toLowerCase().includes(value.toLocaleLowerCase()));
  }
}
@Component({
  ....
    persons;

    ngOnInit() {
         //inicial persons arrays
    }
})

Dan struktur data objek Person:

person.ts

export class Person{
    constructor(
        public firstName: string,
        public lastName: string
    ) { }
}

Dalam tampilan Anda di file html:

your.component.html

    <input class="form-control" placeholder="Search" id="search" type="text" [(ngModel)]="searchText"/>
    <table class="table table-striped table-hover">
      <colgroup>
        <col span="1" style="width: 50%;">
        <col span="1" style="width: 50%;">
      </colgroup>
      <thead>
        <tr>
          <th>First name</th>
          <th>Last name</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let person of persons | searchfilter:searchText">
          <td>{{person.firstName}}</td>
          <td>{{person.lastName}}</td>
        </tr>
      </tbody>
    </table>
Piotr R
sumber
0

Ini array Anda

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

        }
    ];

Ini adalah loop ngFor Anda. Oleh:

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

Di sana saya menggunakan produk instan filterProduct, karena saya ingin menyimpan data asli saya. Di sini model _filterText digunakan sebagai kotak input. Ketika ada perubahan fungsi setter akan memanggil. Dalam setFilterText performProduct disebut itu akan mengembalikan hasil hanya mereka yang cocok dengan input. Saya menggunakan huruf kecil untuk huruf besar-kecil.

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);
        }
Gajender Singh
sumber
0

Setelah beberapa googling, saya menemukan ng2-search-filter . Di akan mengambil objek Anda dan menerapkan istilah pencarian terhadap semua properti objek yang mencari kecocokan.

alindber
sumber
0

Saya menemukan sesuatu untuk membuat filter yang melewati Objek, maka saya dapat menggunakannya seperti multi-filter: Contoh multi-filter

saya melakukan Solusi Kecantikan ini:

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
  });
  });
  }
}

komponen.ts

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

componentset.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">...
Richard Aguirre
sumber