使用 *ngFor 遍历数组,同时还对某个 属性 进行过滤

Using *ngFor to iterate over an array while also filtering on a certain property

在我的 Angular 2 应用程序中,我想知道是否有一种方法可以在遍历数组的同时过滤 *ngFor 块中的某个 属性。所以语法看起来像这样:

<ng-template *ngFor="let flag['completed === false'] of service.flags">
    <span class="standard-flag" 
        [class.hold-flag]="flag?.flagType === 'hold'">Flag
    </span>
</ng-template>

所以基本上逻辑是,对于存在的数组中的每个对象("flag" 是一个对象),其中 "completed" 属性 设置为 "false" ,return那个值。与其先遍历数组,然后使用 *ngIf 进一步过滤,不如在 *ngFor 块中执行这两项操作会更好(并且对我的特定情况非常有帮助)。可能吗?

我对这种构造特别感兴趣的原因是因为我只想 return "completed" 是 "false" 的第一个值,我可以在这种情况下,在 *ngFor 块中使用 "let i = index" 处理它。但我不想 return 所有标志对象中的第一个,只是 "completed" 属性 设置为 "false" 的标志对象。

您可以创建一个 custom pipe 来在您循环遍历 for 循环时过滤项目。

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

@Pipe({name: 'notCompleted'})
export class notCompletedPipe implements PipeTransform {
  transform(value: string]): string {
    return value != 'completed';
  }
}

并像这样在 HTML 中使用它,

<ng-template *ngFor="let flag['completed === false'] of service.flags | notCompleted">
    <span class="standard-flag" 
        [class.hold-flag]="flag?.flagType === 'hold'">Flag
    </span>
</ng-template>

使用管道进行过滤不是一个好主意。请参阅此处的 link:https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

相反,在您的组件中添加代码来执行过滤。然后在过滤后的数据上使用你的 ngFor。

下面是一个例子。然后,在此示例中,您只需对 filteredProducts 使用 ngFor。

import { Component, OnInit } from '@angular/core';

import { IProduct } from './product';
import { ProductService } from './product.service';

@Component({
    templateUrl: './product-list.component.html'
})
export class ProductListComponent implements OnInit {

    _listFilter: string;
    get listFilter(): string {
        return this._listFilter;
    }
    set listFilter(value: string) {
        this._listFilter = value;
        this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
    }

    filteredProducts: IProduct[];
    products: IProduct[] = [];

    constructor(private _productService: ProductService) {

    }

    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) =>
              product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
    }

    ngOnInit(): void {
        this._productService.getProducts()
                .subscribe(products => {
                    this.products = products;
                    this.filteredProducts = this.products;
                },
                    error => this.errorMessage = <any>error);
    }
}