Оператор select создаст наблюдаемый объект, который генерируется каждый раз при обновлении состояния 'feed'. Это сработает в первый раз, когда вы сделаете свой FeedActions.GetFeedCategories()
, но он также сработает снова, когда результат FeedActions.GetFeedItems(...)
будет добавлен к состоянию, что заставит FeedActions.GetFeedItmes(...)
выполняться снова, и снова, и снова ...
Простое решение - добавить дубль (1) в канал, чтобы вы получили только один запуск карты и операторов касания:
ngOnInit() {
this.store.dispatch(new FeedActions.GetFeedCategories());
this.feedSubscription = this.store
.pipe(
select('feed'),
take(1),
map(data => {
this.feedState = data;
return data.categories;
}),
tap(data =>
this.store.dispatch(
new FeedActions.GetFeedItems({
cat_id: data[this.selectedIndex],
page: 0
})
)
)
)
.subscribe(data => {});
}
Однако, возможно, здесь стоит рассмотреть разделение проблем - вы смешали работу по подготовке состояния с работой по выбору состояния для отображения. Лучшее решение может быть примерно таким:
ngOnInit() {
this.store.dispatch(new FeedActions.GetFeedCategories());
this.store.pipe(
select('feed'),
take(1),
map(data => data.categories),
tap(data =>
this.store.dispatch(
new FeedActions.GetFeedItems({
cat_id: data[this.selectedIndex],
page: 0
})
)
)
)
.subscribe(() => {});
this.feedState = this.store.pipe(
select('feed')
);
}
... тогда в вашем шаблоне вы можете использовать {{feedState | async}}?.loading
или что-то еще по мере необходимости.
Канал async
выполняет подписку за вас и ожидает наблюдаемого, а не необработанного поля данных. В вашем примере this.feedState должен иметь тип Observable<FeedState>
, но он выглядит как необработанный тип данных (например, FeedState вместо Observable) из предоставленного кода.
person
Mark Hughes
schedule
29.08.2018