我制作了一个搜索组件,它有一个输入字段,可以在输入时过滤搜索结果列表。我还有一个 websocket,可以将新的或更改的值推送到列表中,如下所示:
this._fooService.foos.subscribe(foos => {
this.foos = foos;
});
Run Code Online (Sandbox Code Playgroud)
当我更改过滤器搜索词时没有过滤器和列表更新时,这很好用。在模板中,它很简单:
<div *ngFor="let foo of foos | filterFoos: searchTerm">
Run Code Online (Sandbox Code Playgroud)
我试过这样做:NgFor 不使用 Angular2 中的管道更新数据
但它没有奏效。我的另一个视图中有相同类型的带有条形的搜索组件,它与过滤器一起工作得很好。虽然有一个承诺,需要在 this.bars = bar 运行之前完成。
编辑:
_fooService.foos 是 Observable<Foo[]>并且在构造函数中初始化:
this.foos = this._fooObservable.asObservable();
Run Code Online (Sandbox Code Playgroud)
其中 _fooObservable 是 BehaviorSubject<Foo[]>并且使用 .next 方法(以及旧的 Foos)向其中添加新的 Foos。
过滤管是这样的:
@Pipe({name: 'filterFoos'})
export class FilterFoosPipe implements PipeTransform {
transform = (foos: Foo[], searchTerm: string = ""): any => {
let filtered = foos.filter((foo) => {
return foo.name.toLowerCase().includes(searchTerm.toLowerCase())
});
return filtered;
}
}
Run Code Online (Sandbox Code Playgroud)
由于您有一个流,您可以使用async-pipe:
<div *ngFor="let foo of _fooService.foos | async | filterFoos: searchTerm">
Run Code Online (Sandbox Code Playgroud)
这样你甚至可以在你的控制器中删除你的自定义订阅,这无论如何都容易发生内存泄漏。异步管道应自动触发 UI 中的更新。
需要注意的第二件事是 ngZone - 在极少数情况下,一些存储更新是在 ngZone 之外触发的,因此不会触发更改检测周期,这可以通过将更新显式包装在ngZone.run 中来解决:
ngZone.run(() => doMyStoreUpdate(...));
Run Code Online (Sandbox Code Playgroud)