0%

angular中使用pipe管道过滤结果集

1. 引子

假设我们需要一个过滤管道来负责过滤应用程序中的列表。

1
import { Pipe, PipeTransform } from '@angular/core';
2
3
@Pipe({ 
4
  name: ‘filter’
5
})
6
export class FilterPipe implements PipeTransform {
7
  transform(arr: string[], searchValue: string) { 
8
    if (!searchValue) return arr;
9
10
    return arr.filter(value => { 
11
      return value.toLowerCase().indexOf(searchValue.toLowerCase()) > -1; 
12
    }); 
13
  }
14
}

这里我们创建来一个数组,通过indexOf方法过滤数组中的元素,最终得到我们想要的列表。
使用方式如下:

1
import { Component } from '@angular/core';
2
import { FormControl } from '@angular/forms';
3
4
@Component({ 
5
  selector: ‘my-app’,
6
   template: `
7
     <input [formControl]="search">
8
     
9
     <div *ngFor=”let item of (items | filter:search.value)”>
10
       {{item}} 
11
     </div>
12
 `
13
})
14
export class AppComponent { 
15
  search = new FormControl(); 
16
  items = [‘One’, ‘Two’, ‘Three’, ‘Four’];
17
}

2. 问题

以上很完美解决了列表过滤的需求,但是这个时候产品想向用户展示检索结果集的数量。大多数时候,我们可能会想,不就是一个数组长度的事儿,有什么难的,然后codeing如下:

1
<div *ngFor=”let item of (items | filter:search.value)”>
2
  {{item}}
3
</div>
4
<p>Count: <b>{{(items | filter:search.value).length}}</b></p>

但是,真不要这么干!你会发现我们写的管道会运行两次。angular4之后这个问题有了解决方案,那就是: as。借助as关键字将管道结果分配给局部变量,还等什么,升级改进我们的代码如下:

1
<div *ngFor=”let item of (items | filter:search.value) as result”>
2
  {{item}} 
3
 </div>
4
{{result.length}}

这个时候你会发现控制台报错了…

1
Cannot read property ‘length’ of undefined

这不是玩我吗?有局部变量啊,为啥还会报错,解决方案是: ngIf

最终的code如下:

1
<ng-container *ngIf=”(items | filter:search.value) as result”>
2
3
  <div *ngFor=”let item of result”>
4
    {{item}}
5
  </div>
6
7
  <p>Count: <b>{{result.length}}</b></p>
8
  
9
</ng-container>