RxJS Observable和正确的方式来构建过滤列表
我已经经历了一堆教程,做了演示等..但我仍然无法包围我的头正确的方式来做到这一点与Observables ...RxJS Observable和正确的方式来构建过滤列表
基本上是我有(在角)是在我的组件2个可变阵列,一个显示列表和项目的fullList ...模板确实上DisplayList中的ngFor。在屏幕上
过滤器调用在清除显示列表组件过滤功能,然后通过fullList循环,如果应用过滤器,它推动它显示列表 - 在屏幕上给人一种实时列表过滤效果...
我知道这是解决这个问题的错误方法,但是我无法将自己的头围绕着需要使用observables做到这一点的架构/模式。我是否会创建一个主列表并根据组件私有属性对其执行.filter()?对于一个返回带有.filter的可观察列表的方法,我该如何做ngFor?
在此先感谢。
是的,是的,不,是,否......换句话说:没有正确的答案,这取决于。 (在你的个人喜好,在一般使用情况下,您的应用程序的现有的架构,等。等...)
过滤控制器
在你的情况,可能并不需要rxjs,尽管如果可能的话应该避免使用可变对象/数据,所以使用.filter
的想法将成为这里的一种方式。
自管
另一种方式去将实现自定义管道和模板将数据直接进行过滤:
<div *ngFor="let item of fullList | customFilterPipe:filterSettings">...</div>
的RxJS路
既然你问了rxjs路,这里是我会怎么做:
filterSettings$: BehaviorSubject<IFilterData> = new BehaviorSubject(INITIAL_FILTER_SETTINGS); // this is updated with filterSettings$.next(newFilterSettings)
fullList$: BehaviorSubject<IData[]> = new BehaviorSubject([]); // updated through fullList$.next(newFullList);
displayList$ = Observable.combineLatest(this.fullList$, this.filterSettings$)
.map(([list, filterSettings]) => {
return list.filter(/* your custom filter based on the filterSettings... */);
});
这将自动更新displayList$
每当filterSettings$
或fullList$
变化。
要在templare使用它,你可以使用async
- 管:
<div *ngFor="let item of displayList$ | async">...</div>
但再次:任何这些解决方案,以及你目前执行的可能是一个完全有效的实现给定情况。
谢谢,这正是我一直在寻找的 –
在RxJS 5本最佳候选是combineLatest()
操作者(它有静态和实例方法变体),当任何其源观测量的发射值,该值调用其选择器的功能。
let userInput$ = Observable.from(['a', 'ac', 'aca', 'acarp'])
.concatMap(char => Observable.of(char).delay(500))
.startWith(null);
let list$ = Observable.of(['abstemious', 'abstentious', 'abulia', 'abut', 'aby', 'acalculia', 'acarophobia', 'acarpous', 'accidence', 'accismus', 'acclamation']);
let filteredList$ = Observable.combineLatest(list$, userInput$, (list, filterString) => {
if (filterString) {
// Note that this is Array.filter() method, not an RxJS operator
return list.filter(name => name.indexOf(filterString) === 0);
}
return list;
});
filteredList$.subscribe(val => console.log(val));
见现场演示:https://jsbin.com/jihuxu/2/edit?js,console
这是模拟的情况下每500ms用户键入一个字符,并相应地过滤list$
。请注意,list$
也可以发出一个新的数组,可以立即进行过滤。
需要注意的一件重要的事情是,每个源Observable必须发出至少一个值,然后.combineLatest()
才能发出每个更改。这就是为什么我也有startWith(null)
,为了确保选定的过滤器在开始时是null
。
除非有一些功能你不能实现,除非你使用observables我认为你的方法听起来不错。您可以为displayList创建一个BehaviorSubject,例如'displayList = new BehaviorSubject([])'并用'displayList.next(newDisplayList)'更新它。然后,您可以在displayFormat | async“'中用'* ngFor =”项在ngFor中绑定它。但我不一定会看到这种方法的好处 – rob