我有一个Angular 4应用程序,它使用angular-router在不同页面之间导航(让我们称之为 pageA 和 pageB )。 pageA 和 pageB 加载相同的项目列表 - sharedState.items (不时重新加载)。以下是这些页面的redux商店结构:
{
pageA: { ... }
pageB: { ..., noItemsMessage: null }
sharedState: { items: [], popupMessage: null, ... }
}
当从服务器成功加载项目时,一切都很好(sharedState会更新,并且两个页面在导航到时都会显示更改)。但是当服务器返回错误时会出现问题 - 我想在弹出窗口中使用 sharedState.popupMessage 在 pageA 上显示错误消息 - 这是显示错误的一般方法应用程序中的弹出窗口但是在 pageB 上,它应该是一个小的本地工具提示,它位于 pageB.noItemsMessage 状态属性中。
我已经注册了redux-observable epics以收听&LOAD_ITEM_FAIL' pageA 和 pageB 副作用的操作,但执行不同的操作,如:
pageALoadItemsFailEpic = actions$ => actions$.ofType('LOAD_ITEM_FAIL')
.switchMap(x => { type: 'SHOW_POPUP', message: 'Error occured' })
pageBLoadItemsFailEpic = actions$ => actions$.ofType('LOAD_ITEM_FAIL')
.switchMap(x => { type: 'UPDATE_PAGE_B_TOOLTIP', message: 'Error occured' })
问题是,当我在 pageB 时 - 会显示错误工具提示并弹出错误消息,因为还会执行 pageALoadItemsFailEpic 。 (而且我不想在 pageB 上显示弹出窗口。)
最简单的方法似乎是跟踪当前导航到哪个页面并根据该页面执行副作用。但我想知道是否有更好的解决方案?或者是否有更好的方法来构建这种功能?有没有办法打开/关闭史诗,根据页面当前是否有效?提前谢谢!
答案 0 :(得分:2)
我不使用redux而是使用ngrx,但我很确定原理是一样的。
您不应在组件外部显示/隐藏UI元素。你应该做的是在你的州有如下属性:
PageAErrors:any,
PageBErrors:any
然后你的PageA组件应订阅PageAErrors
observable和Page B订阅PageBErrors
observable。然后每个组件自己决定做什么(弹出窗口,气球,工具提示,等等),当观察到它的兴趣(有错误)时会发出新的值。
始终坚持基础:这是一种消息传递架构,失去耦合,并且组件之间不应存在直接的,必要的链接<> epics<>状态。 epics fire action,反过来(通过reducer)更新状态,组件监听并对状态变化作出反应。
否则,您最终会在整个代码中维护仅属于组件的UI逻辑(例如,弹出窗口)。