我有一个包含对象对象的数组的可观察对象。 (如图所示)。我有一个observable
从get
请求接收这些值,然后我有另一个observable
用于存储过滤值。我有一个searchText变量binded
到input
我每次输入改变时调用一个函数。
<input name="problem-search" [(ngModel)]="searchText" matInput placeholder="Search for problems..." (input)="filterProblems()">
直到现在,我已经尝试过这个,但它没有产生所需的输出。它有时会过滤,但这是随机的,甚至与searchInput
无关。坦率地说,我甚至不知道我是如何得到那个输出的。 Rxjs有时会令人困惑。请告诉我在这里我做错了什么.
filterProblems() {
if (this.searchText === '') {
this._filteredProblems$ = this._everyProblem$;
}
this._filteredProblems$ = this._everyProblem$.pipe(
map(data => data),
tap(ele => ele.filter(data => {
Object.keys(data).forEach(key => {
if (data[key].name.toLowerCase().includes(this.searchText)) {
delete data[key];
}
});
}))
);
this._filteredProblems$.subscribe(data => console.log(data))
}
tap operator应该用于副作用,并不意味着是流修改操作。以这种方式使用map operator实际上并没有为你做任何事情。我认为您应该从map
样式运算符返回过滤后的对象,以更改流返回的内容,但不会更改正在发出的原始对象。目前,整个对象将返回到流中,减去您从中删除的键。删除后,看起来它们会从原始文件中删除。
使用Object.keys
是一种能够迭代对象的方法,但是在这种情况下,您可以使用Object.values
保存一个步骤,然后从该结果中拉出您想要的键。
这样的东西应该接近你需要的东西:
map((data: yourType[]) =>
data.filter((item: yourType) =>
(!this.searchText || !Object.values(item)[0].name.toLowerCase().includes(this.searchText))
),
或者,您可以设置触发流以监视源数据或输入是否更改。 - 将searchText放在BehaviorSubject中,以便您可以使用它来触发流中的更改。 - 将searchText observable和_everyProblem $ observable与combineLatest结合使用,并将结果设置为_filteredProblems $ - 在内部应用类似的滤镜,以及去抖动
可能有点像这样的东西来激起一些想法:
this._filteredProblems$ = combineLatest(
this.searchTextSubject.asObservable(),
this._everyProblem$,
).pipe(
debounce(() => timer(50))
map((searchText: string, data: yourType[]) =>
data.filter((item: yourType) =>
(!searchText || !Object.values(item)[0].name.toLowerCase().includes(searchText))
),
);