Tìm kiếm trang web

angular - Làm thế nào để áp dụng bộ lọc cho *ngFor?


Rõ ràng, Angular 2 sẽ sử dụng pipe thay vì filter như trong Angular1 kết hợp với ng-for để lọc kết quả, mặc dù cách triển khai vẫn dường như còn mơ hồ, không có tài liệu rõ ràng.

Cụ thể những gì tôi đang cố gắng đạt được có thể được nhìn nhận từ góc độ sau

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

Làm thế nào để triển khai điều đó bằng cách sử dụng ống?

Câu trả lời #1

Về cơ bản, bạn viết một pipe mà sau đó bạn có thể sử dụng trong chỉ thị *ngFor.

Trong thành phần của bạn:

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

Trong mẫu của bạn, bạn có thể truyền chuỗi, số hoặc đối tượng vào ống của bạn để sử dụng lọc theo:

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

Trong ống của bạn:

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

Hãy nhớ đăng ký pipe của bạn trong app.module.ts; bạn không còn cần phải đăng ký các pipe trong @Component của mình nữa

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

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

Đây là một Plunker minh họa việc sử dụng một bộ lọc tùy chỉnh và bộ lọc slice có sẵn để giới hạn kết quả.

Xin lưu ý (như một số bình luận viên đã chỉ ra) rằng có một lý do tại sao không có các ống lọc tích hợp sẵn trong Angular.

Câu trả lời #2

Nhiều bạn có những cách tiếp cận tuyệt vời, nhưng mục tiêu ở đây là phải chung chung và định nghĩa một pipe mảng có thể tái sử dụng cực kỳ trong tất cả các trường hợp liên quan đến *ngFor.

callback.pipe.ts (đừng quên thêm cái này vào mảng khai báo của module của bạn)

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

Sau đó, trong component của bạn, bạn cần triển khai một phương thức với chữ ký sau (item: any) => boolean, trong trường hợp của tôi, ví dụ, tôi gọi nó là filterUser, phương thức này lọc độ tuổi người dùng lớn hơn 18 tuổi.

Thành phần của bạn

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

Và cuối cùng nhưng không kém phần quan trọng, mã html của bạn sẽ trông như thế này:

HTML của bạn

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

Như bạn có thể thấy, Pipe này khá chung cho tất cả các mục giống mảng cần được lọc thông qua một callback. Trong trường hợp của tôi, tôi thấy nó rất hữu ích cho các kịch bản giống *ngFor.

Hy vọng điều này sẽ giúp ích!!!

ma trận mã

Câu trả lời số 3

Đây là những gì tôi đã thực hiện mà không sử dụng pipe.

thành phần.html

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

component.ts

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

Câu trả lời #4

Cách đơn giản (Chỉ sử dụng trên các mảng nhỏ vì vấn đề hiệu suất. Với các mảng lớn, bạn phải tự lập bộ lọc bằng mã):

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

Cách sử dụng :

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

Nếu bạn sử dụng một biến làm đối số thứ hai, đừng dùng dấu ngoặc kép.

Câu trả lời số 5

Tôi không chắc nó xuất hiện khi nào nhưng họ đã làm ống cắt lát có thể làm được điều đó. Nó cũng được tài liệu hóa đầy đủ.

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>

Câu trả lời số 6

Một giải pháp đơn giản hoạt động với Angular 6 để lọc một ngFor, như sau:

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

Các khoảng thời gian hữu ích vì chúng không đại diện cho bất cứ điều gì một cách cố hữu.

Câu trả lời số 7

Bạn cũng có thể sử dụng những điều sau:

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

Điều này sẽ chỉ hiển thị div nếu các mục của bạn khớp với điều kiện

Xem tài liệu Angular để biết thêm thông tin. Nếu bạn cũng cần chỉ mục, hãy sử dụng cái sau:

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

Bài viết liên quan