我正在努力寻找使用RxJS 6过滤对象数组的正确方法。
这是场景。我有users: User[]
,filter: FormControl
和另一个数组filteredUsers: User[]
。我想做的是根据filter
中包含的值过滤用户列表。我能够弄清楚的唯一方法是使用tap
,尽管这样做可行,但这似乎不是正确的方法...加上整个列表都被“过滤掉”,直到过滤器控件的第一个valueChange。
this.filter.valueChanges.pipe(
tap((term) => {
this.filteredUsers = this.users.filter(u => u.name.indexOf(term) != -1)
})).subscribe()
任何帮助将不胜感激。
答案 0 :(得分:2)
您是对的,水龙头不是“正确”的操作方式...正确的方法是在订阅中进行操作...
this.filter.valueChanges.pipe(startWith('')).subscribe(
(term) => {
this.filteredUsers = (term) ? this.users.filter(u => u.name.indexOf(term) != -1) : this.users;
});
并添加一个未过滤的空白支票,并从此开始。完成和完成。不要在不需要的地方增加复杂性。 rxjs建议您的订阅功能中出现副作用,其他所有功能都应具有转化性/功能,并且在控制器上设置值是一种副作用。
如果您想变得反应灵敏,可以投入异步管道以取得良好的效果
this.filteredUsers$ = this.filter.valueChanges.pipe(startWith('')).tap(
(term) => {
return (term) ? this.users.filter(u => u.name.indexOf(term) != -1) : this.users;
});
然后用HTML代替
*ngFor="let user of filteredUsers"
这样做:
*ngFor="let user of filteredUsers$ | async"
这里的好处是自动清除订阅并更好地支持onpush更改检测。
答案 1 :(得分:0)
只需将点击功能移到订阅中:
this.filter.valueChanges.subscribe((term) => {
this.filteredUsers = this.users.filter(u => u.name.indexOf(term) != -1)
});