在我们的申请中
容器组件
如下所示:
export class ArchiveAllComponent implements OnInit {
archiveAllViewModel$: Observable<ArchiveAllViewModel>
constructor(
private store: Store<ApplicationState>,
private votingService: VotingService
) { }
ngOnInit() {
// Subscribe to any changes in the category and voting entities
this.archiveAllViewModel$ = this.store.pipe(
select(selectCategoriesWithVoting),
map((categories: Category[]) => mapToArchiveAllViewModel(categories))
)
// Load all categories
this.votingService.getCategories().subscribe((categories: Category[]) => {
this.store.dispatch(new LoadCategoryAction(categories));
});
// Load all votings
this.votingService.getVotings().subscribe((votings: Voting[]) => {
this.store.dispatch(new LoadVotingAction(votings));
});
}
}
一旦这个组件被呈现,两个HTTP GET请求将被执行到不同的API。
对于每一个请求
是
致
商店
减速器
// Reducer function
export function entityReducer(currentState: Entities, action: EntityActionsUnion): Entities {
switch (action.type) {
case EntityActionTypes.LOAD_CATEGORIES:
return merge({}, currentState, {categories : action.categories});
case EntityActionTypes.LOAD_VOTINGS:
return merge({}, currentState, {votings : action.votings});
default:
return currentState;
}
}
export function selectCategoryEntity(state: ApplicationState) {
return state.entities.categories;
}
export function selectVotingEntity(state: ApplicationState) {
return state.entities.votings;
}
export const selectCategoriesWithVoting = createSelector(
selectCategoryEntity,
selectVotingEntity,
(categoryEntities: Category[], votingEntities: Voting[]) => {
if (categoryEntities && categoryEntities.length > 0 && votingEntities && votingEntities.length > 0) {
let categories = categoryEntities.slice();
votingEntities.forEach(voting => {
if (voting.categoryId) {
let category = categories.find(x => x.id == voting.categoryId);
if(!category.votings)
{
category.votings = [];
}
category.votings.push(voting);
}
});
return categories;
}
return [];
}
);
这个
archiveAllViewModel$
然后,observable被传递给一些子组件,以便相应地呈现HTMl。
-
页面刷新
-
getCategories()
-
getVotings()
+动作/减速器被触发
-
<archiveElement>
-
<架构元素>
+正确呈现第二个子元素
-
<架构元素>
当我开始离开组件并通过客户端站点路由返回到同一路由时,问题就开始出现。
<a routerLink="/someotherpage" routerLinkActive="active" mat-button>Other Page</a>
返回到同一组件:
<a routerLink="/archiveAll" routerLinkActive="active" mat-button>Archive</a>
现在,与整页刷新相比,所有内容都呈现两次:
-
远航
-
-
<架构元素>
-
<架构元素>
-
<架构元素>
-
获取类别()
+动作/减速器被触发
-
<
-
<
-
<架构元素>
-
获取votings()
+动作/减速器被触发
-
<
-
<架构元素>
-
<
因此
.
故障排除
createSelector
现在对每个http请求执行一次,因为
categoryEntities && categoryEntities.length > 0 && votingEntities && votingEntities.length > 0
不再仅对第二个http请求有效
.