如何在Angular2中执行自定义过滤器管道?

3

我可以帮助您翻译有关IT技术的内容,以下是需要翻译的内容:

我在 Angular2 中使用自定义过滤器时遇到了问题。

我的情况如下:

我的页面包含多个自定义组件。其中一个组件负责在页面左侧显示数据:(组件A)

  <md-list-item *ngFor="let item of items | filter :  filter | sort:   sort; let i = index"  " >
       <template [render]="itemTemplateRef" [context.item]="item" 
       [context.index]="index"></template>
   </md-list-item>

另外,筛选是通过自定义筛选来完成的:

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



@Pipe({ name: 'filter' })

export class FilterPipe implements PipeTransform {
    transform(values: any[], filter: any): any {
        if (typeof filter !== "function") return values;
          return values.filter((elem) => {
             return filter(elem);
        });
    }
}

在主页面中,我将一个函数作为输入属性发送到组件A中:
   public filter = (element: MyBean) => {
             return (element.email !== undefined);

    }

在页面加载时,它可以顺利执行。但是我想通过点击复选框来多次更改过滤条件。

我知道这个事实,如果输入值更改,就会执行纯过滤。

但是我不知道,在我的情况下应该更改哪个输入值才能强制进行过滤?当我在复选框的Onchange事件中添加以下函数时,没有任何过滤(items绑定到我的组件显示的数据)。

    createFilterCondition = (searchCondition: string) => {

        items.filter((element) => {
            return this.doFilter(elem);
        });
    }
   public doFilter= (element: MessagesBean) => {

        return (element.email !== undefined);
    }

感谢您的帮助。
2个回答

8

有两种方法

使管道变得不纯

@Pipe({ name: 'filter', pure: false })

缺点是管道将被频繁执行(每次运行变更检测时都会执行)。您可以通过缓存结果并仅在参数更改时进行过滤来优化,但检查数组是否已修改也不便宜。

另一种方法是向管道传递附加参数。如果值或管道的参数发生更改,Angular会再次执行该管道

@Pipe({ name: 'filter' })

export class FilterPipe implements PipeTransform {
    transform(values: any[], filter: any, changeIndicator: number): any {
        if (typeof filter !== "function") return values;
          return values.filter((elem) => {
             return filter(elem);
        });
    }
}

现在,您只需要在组件中递增changeIndicator,就可以让Angular在下一次变更检测运行时再次执行该管道。


1
感谢您的回应。 通过创建一个新数组解决了这个问题。如果这不是一个好的过滤方式,请告诉我。
以下是我所做的:
我通过创建另一个数组而不是原始数组(名为filteredArray)来处理它。
并将筛选结果保留在其中,因此将filterArray绑定到我的组件中。我意识到数组上的filter方法返回一个新数组,因此将结果放入新变量中:
 this.filteredArray = this.records.filter((element) => {
            return this.filterSms(element);
        }); 

public filterSms = (element: MessagesBean) => {
          return (element.mobile !== undefined);
}

这是一个常见的解决方法。它是好是坏主要取决于创建数组副本的成本有多高。如果它只有<100个项目并且不经常更改,那么可能还可以。如果有几千个项目,那么我的方法可能会更有效。 - Günter Zöchbauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接