1. 引子
假设我们需要一个过滤管道来负责过滤应用程序中的列表。
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: ‘filter’
})
export class FilterPipe implements PipeTransform {
transform(arr: string[], searchValue: string) {
if (!searchValue) return arr;
return arr.filter(value => {
return value.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
});
}
}
这里我们创建来一个数组,通过indexOf方法过滤数组中的元素,最终得到我们想要的列表。
使用方式如下:
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: ‘my-app’,
template: `
<input [formControl]="search">
<div *ngFor=”let item of (items | filter:search.value)”>
{{item}}
</div>
`
})
export class AppComponent {
search = new FormControl();
items = [‘One’, ‘Two’, ‘Three’, ‘Four’];
}
2. 问题
以上很完美解决了列表过滤的需求,但是这个时候产品想向用户展示检索结果集的数量。大多数时候,我们可能会想,不就是一个数组长度的事儿,有什么难的,然后codeing如下:
<div *ngFor=”let item of (items | filter:search.value)”>
{{item}}
</div>
<p>Count: <b>{{(items | filter:search.value).length}}</b></p>
但是,真不要这么干!你会发现我们写的管道会运行两次。angular4之后这个问题有了解决方案,那就是: as。借助as关键字将管道结果分配给局部变量,还等什么,升级改进我们的代码如下:
<div *ngFor=”let item of (items | filter:search.value) as result”>
{{item}}
</div>
{{result.length}}
这个时候你会发现控制台报错了...
Cannot read property ‘length’ of undefined
这不是玩我吗?有局部变量啊,为啥还会报错,解决方案是: ngIf
最终的code如下:
<ng-container *ngIf=”(items | filter:search.value) as result”>
<div *ngFor=”let item of result”>
{{item}}
</div>
<p>Count: <b>{{result.length}}</b></p>
</ng-container>
网友评论