简体   繁体   English

为什么 CombineLatest 会修改 observable

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM