如何强制自定义过滤管道在angular2中执行

时间:2016-10-14 00:23:58

标签: angular filter pipe

我在angular2中有自定义过滤的问题。

这是我的情景:

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

  <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事件中添加以下函数时,没有任何内容被过滤。(项目绑定到我的组件显示的数据中)

    createFilterCondition = (searchCondition: string) => {

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

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

感谢您的帮助

2 个答案:

答案 0 :(得分:6)

有两种方式

使管道不纯净

@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 :(得分:1)

感谢您的回复。 它通过创建一个新数组来解决。如果这不是一个好的过滤方式,请通知我。

以下我描述了我的所作所为:

我通过创建另一个数组而不是原始数组来处理它。(名为filteredArray)

并保留过滤器的结果,因此,将filterArray绑定到我的组件中。我意识到数组上的filter方法返回一个新数组。所以把结果放在新变量中:

 this.filteredArray = this.records.filter((element) => {
            return this.filterSms(element);
        }); 

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