【发布时间】:2019-12-14 20:05:18
【问题描述】:
我对 RxJS observable 有一个奇怪的行为,我不知道为什么。
我有一个服务,它公开 BehaviorSubject 并发出事件:
@Injectable({
providedIn: 'root'
})
export class SearchService {
private searchSubject: BehaviorSubject<SearchQueryParams>;
updateSearch(search: any) {
this.searchSubject.next(search);
}
onSearchUpdate(): Observable<any> {
return this.searchSubject.asObservable();
}
}
在我的组件中,我使用shareReplay() 订阅了这个Observable,因为我在模板中使用了多个async 管道:
@Component({
selector: 'rp-produit-recherche',
template: '<div class="search">
<app-facets class="facets" [facets]="searchResult$ | async"></app-facets>
<app-results [results]="searchResult$ | async"></app-results>
</div>
',
styleUrls: ['./produit-recherche.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchComponent implements OnInit {
public searchResult$: Observable<any>;
...
ngOnInit() {
this.searchResult$ = this.SearchService.onSearchUpdate().pipe(
switchMap((searchRequest) => {
return this.apiService.search(searchRequest);
}),
shareReplay()
);
}
}
这实际上工作正常。当一个事件发出时,调用 api 并且结果就是我想要的。
现在我添加了第二个 Route 服务于相同的组件。我的问题已经开始了。
当我从路线 a 导航到路线 b 时。事件仍然被发出,但在订阅中它被接收了两次。如果我在这些路线之间再次导航,我会得到 n 个事件 + 1,等等。
我的路线:
{
path: '',
children: [
{
path: '',
resolve: {
searchQueryParams: SearchQueryParamsResolverGuard
},
children: [
{
path: 'a',
component: SearchComponent,
},
{
path: 'b',
component: SearchComponent
}
]
}
]
}
以及发出事件的解析器:
@Injectable({
providedIn: 'root'
})
export class SearchQueryParamsResolverGuard implements Resolve<any> {
constructor(private searchService: SearchService) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): SearchQueryParams {
const search = route.queryParamMap.get('search');
return this.searchService.updateSearch(search);
}
}
我不明白为什么会这样。导航时组件被破坏,因此订阅应该已经结束。
我希望有人已经遇到此问题并找到解决方法。谢谢
【问题讨论】:
-
何时调用
this.SearchService.updateSearch()? -
在几个地方,但在这种情况下在
SearchQueryParamsResolverGuardresolver -
我可能找到了问题的根源:
shareReplay()如果我删除它,问题就解决了,但在模板中Observable是在多个地方订阅的。但我只需要调用一次 api 并共享数据。share()似乎更适应。我需要了解差异。 -
请尝试
shareReplay(1)@MartinChoraine -
@MartinChoraine,请检查更新的答案
标签: angular rxjs observable