模板Angular2中的过滤器数组

Filter array in template Angular2

我正在尝试制作简单的模板,但遇到了一些小问题。我想在我的待办事项列表中打印未完成任务的数量,但无法在模板中过滤它们。我有这个:

<span class="todo-count"><strong>{{todos.length}}</strong> left</span>

但我想过滤此待办事项以仅计算状态已完成设置为 false 的待办事项:

<span class="todo-count"><strong>{{todos.filter(t => !t.complete).length}}</strong> left</span>

但这不起作用。我怎样才能做到这一点?

我使用 lodash 来解决这类问题。

你可以这样安装... https://medium.com/@gtsopour/importing-lodash-into-angular-2-typescript-application-94590365f46d#.bsepr3agd

然后使用它的过滤功能过滤视图中的数组... https://lodash.com/docs/4.17.4#filter

让它成为一个应用你标准的函数:

<span class="todo-count"><strong>{{filterValue()}}</strong> left</span>

在你的控制器中

      filterValue() : number 
      { 
          return todos.filter(...);
       }

最正确的方法是使用 Angular 管道:

模板

<span class="todo-count"><strong>{{ (todos | filter : filterFunction).length }}</strong> left</span>

管道

import {
    Injector,
    Pipe,
    PipeTransform
} from '@angular/core';
@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {

    public constructor(private readonly injector: Injector) {
    }

    transform(value: Array<any>, callback: any): any {
        return value.filter(callback);
    }
}

组件控制器中的filter函数

filterFunction(t): boolean {
  return !t.complete;
}

您可以在此处 Don't Use Functions Inside Angular Templates and What to Use Instead 了解为什么不使用 angular 模板中的方法。简而言之,这是因为 Angular 中的变化检测机制。 Angular 无法检测函数的结果是否已更改,直到它 运行 成为函数函数。

需要考虑的是函数将是 运行 即使我们有相同的输入数据

我写了一个简单的 Angular 管道,允许您将对象或回调函数作为过滤器传递。

请看下面的例子:

home.component.ts

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent {
  array = [
    {type: 'log', name: 'Log 1'},
    {type: 'log', name: 'Log 2'},
    {type: 'log', name: 'Log 3'},
    {type: 'log', name: 'Log 4'},
    {type: 'event', name: 'Event 1'},
    {type: 'event', name: 'Event 2'},
    {type: 'event', name: 'Event 3'},
    {type: 'event', name: 'Event 4'}
  ];

  complexFilter = (item, index) => item.type === 'event' && index % 2 !== 0;
}

home.component.html

<h1>All items</h1>
<div *ngFor="let item of array">
  {{item.name}}
</div>

<h1>Only logs</h1>
<div *ngFor="let item of array | dynamicFilter: { type: 'log'}">
{{item.name}}
</div>

<h1>Complex filter</h1>
<div *ngFor="let item of array | dynamicFilter: complexFilter">
  {{item.name}}
</div>

输出将是

All items
Log 1
Log 2
Log 3
Log 4
Event 1
Event 2
Event 3
Event 4
   
Only logs
Log 1
Log 2
Log 3
Log 4

Complex filter
Event 2
Event 4

如您所见,您可以在模板中提供一个简单的过滤器对象或一个复杂的过滤器回调函数。

您可以找到 dynamicFilter 管道的源代码 here