当前位置:  开发笔记 > 编程语言 > 正文

如何将过滤器应用于*ngFor?

如何解决《如何将过滤器应用于*ngFor?》经验,为你挑选了7个好方法。

显然,Angular 2将使用管道而不是Angular1中的过滤器以及ng-for来过滤结果,尽管实现似乎仍然模糊,没有明确的文档.

也就是说,我想要实现的目标可以从以下角度来看待

如何使用管道实现?



1> phuc77..:

基本上,你编写一个管道然后可以在*ngFor指令中使用.

在您的组件中:

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

在模板中,您可以将字符串,数字或对象传递给管道以用于过滤:

  • 在你的管道中:

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

    记得注册你的管道app.module.ts; 你不再需要在你的管道中注册管道了@Component

    import { MyFilterPipe } from './shared/pipes/my-filter.pipe';
    
    @NgModule({
        imports: [
            ..
        ],
        declarations: [
            MyFilterPipe,
        ],
        providers: [
            ..
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    这是一个Plunker,它演示了使用自定义过滤器管道和内置切片管道来限制结果.

    请注意(正如几位评论员指出的那样)Angular中没有内置过滤管道的原因.


    Thanx,这项工作按预期进行,但有时最好检查items数组是否已定义且不为null,因为Ng2可能会尝试应用过滤器,而"items"仍未定义.
    我想建议在括号中包装`* ngFor`参数,以避免任何混淆并使它“防更改”:`<li * ngFor =“让(items | myfilter:filterargs)”>项目

    2> code5..:

    很多人都有很好的方法,但这里的目标是通用并定义一个数组管道,它在与*ngFor的关系中可以非常重复使用.

    callback.pipe.ts(不要忘记将它添加到模块的声明数组中)

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

    然后在你的组件中,你需要实现一个具有以下signuature的方法(item:any)=> boolean,在我的例子中,我称之为filterUser,它过滤用户的年龄大于18岁.

    你的组件

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

    最后但并非最不重要的是,您的HTML代码将如下所示:

    你的HTML

  • {{user.name}}
  • 正如您所看到的,此管道在所有数组中都非常通用,例如需要通过回调过滤的项目.在我的案例中,我发现它对*ngFor类似场景非常有用.

    希望这可以帮助!!!

    codematrix


    为了避免"this"未定义的问题,你可以在你的组件上编写你的方法,比如`filterUser =(user:IUser)=>`而不是`filteruser(user:IUser)`
    我注意到在函数filterUser()中 - 或者我的等效函数 - 你不能像使用组件类中的所有其他函数那样使用"this"来访问当前组件实例.我需要访问组件对象以检查过滤后的项目是否在集合中.

    3> Rodolfo Jorg..:

    简化方式(由于性能问题仅在小型阵列上使用.在大型阵列中,您必须通过代码手动生成过滤器):

    请参阅:https://angular.io/docs/ts/latest/guide/pipes.html#!#no-filter-pipe

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

    用法:

  • {{it}}
  • 如果使用变量作为第二个参数,请不要使用引号.


    根据Angular团队的说法,这被认为是不好的做法.
    可能添加以下内容以显示如何将其与ReqExp结合使用:return items.filter(item => {return new RegExp(value,"i").test(item [field])});
    根据Angular团队的说法,这是一个糟糕的代码,因为它很慢并且没有很好地缩小.由于他们的代码,团队不希望看到慢速网站,所以他们这次没有将它构建到Angular中.https://angular.io/docs/ts/latest/guide/pipes.html#!#appendix-no-filterpipe-or-orderbypipe-

    4> Thang Le..:

    这是我在不使用管道的情况下实现的.

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


    我认为这将是计算密集型的,因为Angular每次运行变化检测时都会执行过滤器.它不能很好地扩展到大型阵列.一个更干净但代码更复杂的解决方案是使`itemList`成为一个Observable并使用异步过滤器:`let item of itemsList | async`.发生更改时,使observable发出新列表.这样,过滤代码仅在需要时运行.

    5> SpaceBeers..:

    我不确定它什么时候进来,但是他们已经制作了切片管来做到这一点.它也有很好的记录.

    https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html

    {{ feature.description }}


    如果使用[trackBy接口](https://angular.io/docs/ts/latest/api/core/index/TrackByFn-interface.html),切片管道必须在`;`之前应用.例如:`*ngFor ="让内容的特征?.keyFeatures |切片:1:5; trackBy特征?.id"`

    6> Jeroen..:

    您还可以使用以下内容:

    
    

    如果您的商品符合条件,则仅显示div

    有关详细信息,请参阅角度文档.如果还需要索引,请使用以下命令:

    
    



    7> Ben Glasser..:

    Angular2中的管道与命令行上的管道类似.每个先前值的输出都被送入管道之后的过滤器,这样就可以很容易地链接过滤器,如下所示:

    
    


    不支持同一元素上的`*ngFor`和`*ngIf`.你需要改变其中一个`