显然,Angular 2将像在Angular1中一样使用管道而不是过滤器,并结合ng-for来过滤结果,尽管实现看起来仍然很模糊,没有明确的文档。

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

<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>

如何实现这样使用管道?


当前回答

这是我在没有使用管道的情况下实现的。

component.html

<div *ngFor="let item of filter(itemsList)">

component.ts

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

其他回答

下面给出了限制ngFor的最简单易行的方法

<li *ngFor="let item of list | slice:0:10;Let i=index" class="dropdown-item" >{{item.text}}</li> .text}

我喜欢用于特定于应用程序的过滤器的另一种方法是在组件上使用自定义只读属性,这允许您比使用自定义管道(IMHO)更清晰地封装过滤逻辑。

例如,如果我想绑定到albumList并过滤searchText:

searchText: "";
albumList: Album[] = [];

get filteredAlbumList() {
    if (this.config.searchText && this.config.searchText.length > 1) {
      var lsearchText = this.config.searchText.toLowerCase();
      return this.albumList.filter((a) =>
        a.Title.toLowerCase().includes(lsearchText) ||
        a.Artist.ArtistName.toLowerCase().includes(lsearchText)
      );
    }
    return this.albumList;
}

要在HTML中绑定,你可以绑定到只读属性:

<a class="list-group-item"
       *ngFor="let album of filteredAlbumList">
</a>

我发现对于特定于应用程序的专用过滤器,这比管道工作得更好,因为它保持了与组件过滤器相关的逻辑。

管道对于全局可重用过滤器工作得更好。

很多人都有很好的方法,但这里的目标是通用的和定义的数组管道,它在与*ngFor相关的所有情况下都是非常可重用的。

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

然后在您的组件中,您需要实现一个具有以下signature (item: any) => boolean的方法,例如,在我的示例中,我将其称为filterUser,用于过滤大于18岁的用户的年龄。

您的组件

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

最后,你的html代码看起来是这样的:

HTML

<li *ngFor="let user of users | callback: filterUser">{{user.name}}</li>

正如您所看到的,这个Pipe对于所有需要通过回调筛选的数组(如项目)都是相当通用的。在我的例子中,我发现它对于*ngFor之类的场景非常有用。

希望这能有所帮助!!

codematrix

理想情况下,您应该为此创建angualr 2管道。但是你可以做这个魔术。

<ng-container *ngFor="item in itemsList">
    <div*ngIf="conditon(item)">{{item}}</div>
</ng-container>

基于上面提出的非常优雅的回调管道解决方案,可以通过允许传递额外的过滤器参数来进一步泛化它。然后我们有:

callback.pipe.ts

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

@Pipe({
  name: 'callback',
  pure: false
})
export class CallbackPipe implements PipeTransform {
  transform(items: any[], callback: (item: any, callbackArgs?: any[]) => boolean, callbackArgs?: any[]): any {
    if (!items || !callback) {
      return items;
    }
    return items.filter(item => callback(item, callbackArgs));
  }
}

组件

filterSomething(something: Something, filterArgs: any[]) {
  const firstArg = filterArgs[0];
  const secondArg = filterArgs[1];
  ...
  return <some condition based on something, firstArg, secondArg, etc.>;
}

html

<li *ngFor="let s of somethings | callback : filterSomething : [<whatWillBecomeFirstArg>, <whatWillBecomeSecondArg>, ...]">
  {{s.aProperty}}
</li>