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

痴心易碎 提交于 2021-02-07 10:24:30

问题


In my Angular 2 app I am wondering if there's a way I can iterate over an array while also filtering on a certain property in the *ngFor block. So the syntax would look something like this:

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

So basically the logic is, for each object ("flag" is an object) in the array that exists, where the "completed" property is set to "false", return that value. Rather than first iterating over the array, and then using *ngIf to filter further, it'd be nice (and very helpful in my particular situation) if I could do both in the *ngFor block. Possible?

The reason why I'm interested in this kind of construction specifically is because I want to return only the first of the values where "completed" is "false", and I could handle that with "let i = index" in the *ngFor block in that case. But I don't want to return the first of ALL flag objects, just the flag objects where the "completed" property is set to "false".


回答1:


It's not a good idea to use a pipe for filtering. See the link here: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

Rather, add code in your component to perform your filtering. Then use your ngFor over the filtered data.

Below is an example. Then you would just use ngFor over the filteredProducts in this example.

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



回答2:


You can create a custom pipe to filter the items when u loop over an for loop.

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

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

and Use it in HTML like this,

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


来源:https://stackoverflow.com/questions/45443296/using-ngfor-to-iterate-over-an-array-while-also-filtering-on-a-certain-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!