使用自定义过滤器和订阅

时间:2017-03-02 14:06:41

标签: angular rxjs

我创建了一个搜索组件,其中有一个输入字段,用于在键入时过滤搜索结果列表。我还有一个websocket,它将新值或更改的值推送到列表中,如下所示:

this._fooService.foos.subscribe(foos => {
    this.foos = foos;
});

当我更改过滤器搜索词时,如果没有过滤器和列表更新,这可以正常工作。在模板中它只是:

<div *ngFor="let foo of foos | filterFoos: searchTerm">

我尝试过这样做:NgFor doesn't update data with Pipe in Angular2

但它没有奏效。我在其他视图中使用相同类型的搜索组件,并且它与过滤器一起正常工作。虽然有一个承诺,需要在this.bars = bars之前完成。

编辑:

_fooService.foos是Observable <Foo[]>,它在构造函数中初始化:

this.foos = this._fooObservable.asObservable(); 

其中_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;
  }
}

1 个答案:

答案 0 :(得分:4)

由于您有流,因此可以使用async-pipe

<div *ngFor="let foo of _fooService.foos | async | filterFoos: searchTerm">

这样你甚至可以在你的控制器中删除你的自定义订阅,这很容易发生内存泄漏。 async-pipe应自动触发UI中的更新。

要注意的第二件事是ngZone - 在极少数情况下,某些商店更新是在ngZone之外触发的,因此不会触发更改检测周期,这可以通过明确地将更新包装在一个ngZone.run

ngZone.run(() => doMyStoreUpdate(...));