[英]Why does CombineLatest modify observable
In my Angular app I have this simple stream for a search bar.在我的 Angular 应用程序中,我有一个简单的搜索栏流。
.ts .ts
user$: Observable<User> = this.authService.user$;
ally$: Observable<UserAndMatch> = this.user$.pipe(
switchMap((user: User) =>
this.userService.getFollowing(user)
shareReplay(1),
);
filteredAlly$: Observable<UserAndMatch> = new Observable<UserAndMatch>();
@ViewChild('search') search: ElementRef;
ngAfterViewInit() {
const query$ = fromEvent(this.search.nativeElement, 'input').pipe(
debounceTime(200),
map(() => this.search.nativeElement.value),
startWith(''),
map((query: string) => query.trim().toLowerCase()),
distinctUntilChanged(),
);
this.filteredAlly$ = combineLatest([query$, this.ally$]).pipe(
map(([query, ally]: [string, UserAndMatch]) => {
return !query ? ally : this.allyFilter(ally, query)
}),
);
}
allyFilter(ally, query) {
ally.users = ally.users.filter(user => user.name.includes(query));
return ally;
}
.html .html
<form autocomplete="off">
<input
#search
/>
</form>
<ng-container *ngrxLet="filteredAlly$ as ally"></ng-container
The stream works as expected when typing a word, but when the user deletes some letters the array from filteredAlly$
doesn't repopulate and, logging the values in the ally$
pipeline, I found out that ally$
values are being filtered too, while I wanted them to be a "backup" to apply some filter function to which should return filteredAlly$
当输入一个单词时,流按预期工作,但是当用户删除一些字母时,
filteredAlly$
中的数组不会重新填充,并且在ally$
管道中记录值,我发现ally$
值也被过滤了,而我希望它们成为一个“备份”来应用一些应该返回filteredAlly$
的过滤函数
The probable culprit is the first line of allyFilter
:可能的罪魁祸首是
allyFilter
的第一行:
ally.users = ally.users.filter(user => user.name.includes(query));
You're modifying ally.users
in place, instead of creating a copy.您正在就地修改
ally.users
,而不是创建副本。 This means that you're shortening the list of allies when the user is typing, and you're not getting a "fresh" copy of allies later, when the user deletes the characters.这意味着您在用户键入时缩短了盟友列表,并且稍后当用户删除字符时您不会获得盟友的“新”副本。
It will probably suffice to shallow-copy ally object in allyFilter, like so:在 allyFilter 中浅拷贝 ally 对象可能就足够了,如下所示:
allyFilter(ally, query) {
return {
...a11y,
users: ally.users.filter(user => user.name.includes(query));
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.