我正在以角度开发我的第一个ngrx应用程序并且遇到相关实体的问题。我有两个减速器,一个叫做Page,叫做Section。下面是结构的简化版本。 section对象有一个pagesIds的pages数组,指向页面reducer中的页面。
// section.reducer.ts
sections: {
1: {
id: 1,
title: 'Section 1',
pages: [1,2,3]
}
}
// page.reducer.ts
pages: {
1: {
id: 1,
title: 'Page 1'
},
2: {
id: 2,
title: 'Page 2'
}
3: {
id: 3,
title: 'Page 3'
}
}
我想要的是当我想添加一个新的页面并将其添加到一个部分时。我的第一个想法是调度AddPage操作并在两个reducers中处理它。那么问题是页面对象是在页面缩减器中创建的,因此缩减器部分并不知道它。我必须至少在section reducer中有pageId。然后我想我可以使用新创建的页面调度AddPageSuccess,以便节段缩减器可以处理它。这种方法的问题是在减速器中没有对商店的引用,所以我不能发送任何动作。因此我尝试将其添加为@effect。这可能会奏效,但我不确定它是否是正确的"通往它的方式。我的印象是效果应该用于异步数据,比如休息调用。在这种情况下,一切都是同步的,但具有相互依赖的动作。 @effects是"有效"实现这种情况的方法,其中动作相互依赖或者这种设计是错误的。
另一种方法是让所有状态都在同一个reducer中,但是reducer会很大,因为每个部分都会有很多逻辑。
答案 0 :(得分:0)
效果是副作用,你认为效果解决方案在我看来完全有效。您正在添加Page,但Section也应该知道这一点。这绝对是一个副作用吧?所以,效果是一个很好的解决方案。
答案 1 :(得分:0)
@Effects适用于带副作用的动作。你到目前为止已经提到了纯粹的行为(这些没有副作用),所以这些应该由reducer处理。
你应该有两个动作,每个动作对应一个:
ADD_SECTION_PAGE
ADD_PAGE
如果要添加页面并将其添加到该部分,请从商店发送两条消息:
onAddPage() {
this.store.dispatch(new AddSectionPageAction({sectionId:1, page:4 }));
this.store.dispatch(new AddPageAction({ id:4, title: 'Some Page Title' }));
}
SectionReducer会找到基于sectionId的部分,并将新页面添加到pages数组中。
PageReducer会将页面添加到PageState。
ID的计算可以在reducer中进行:
newId = Object.keys(pagesState).length > 0
? Object.keys(pagesState).sort().reverse()[0] + 1 : 1;
或者,如果您通过Web API调用添加页面,请通过@effect添加页面,并将ID传递给ADD_PAGE操作。
答案 2 :(得分:0)
基于https://medium.com/@viestursv/how-to-get-store-state-in-ngrx-effect-fab9e9c8f087
您可以访问Effect类中的状态。请参阅下面的相关代码。选择器是一种制作状态切片的方法,你必须在reducer中调度带有相关数据的状态才能更新状态。
```
@Effect() specialEffect$ = this.actions$
.ofType(ADD_LINE)
.withLatestFrom([
this.store$.select(state => state.lines),
this.store$.select(state => state.pages])
.map(([action: Action, linesOrPages: Lines|Pages]) => {
// Do something ...
});