角5+,ngrx 4 +
当ARTICLES_LIST_REQUEST
初始化与ArticlesListComponent
path
相关联的/articles
时,我尝试做的是触发dispatch
。
有很多方法可以使用ngOnInit
内的dispatch
,例如在警卫上使用@ngrx/router-store
,但我想要做的是使用{{1听取ROUTER_NAVIGATION
并将其映射到ARTICLES_LIST_REQUEST
(实际上是ARTICLES_LIST_PARAMS_SET
,将当前路线参数保存到商店,但这没关系),现在有几个问题那个。
由于效果,即使是forFeature
注册的效果,也在全球范围内运行,如果我设置此效果,在多个模块(文章,人物,品牌等)内听ROUTER_NAVIGATION
,它会多次运行,一次触发所有动作,所以我需要一种方法来过滤它只对我感兴趣的路线..但是如何?由于角度路由器中没有命名路由,导航操作返回整个树的快照,因此无法知道刚刚激活的特定路由。我目前正在做的是通过网址进行检查和过滤,例如,它是以/articles
开头,以及下一个字符是否不是/
(以过滤掉/articles/<id>
。但是我真的不喜欢它,并不觉得它能安全地覆盖所有情况。
曾经有一种方法可以在组件内暂停/启动/取消订阅/订阅效果,我认为这种方式不再可行,但它会将责任转移回组件,这不会太多比从组件/后卫调度动作更好。
我根本不应该使用router-store
吗?
答案 0 :(得分:1)
这是我最终的结果:
1)为路由定义的name
data
export const ROUTES: Routes = [
{
path: '/articles',
component: ArticlesListPage,
data: {
name: 'articles-list'
}
}
];
2)为router-store
创建一个自定义serializer,每个params
只提取queryParams
,name
和data.name
(来自function createSerializedTree(node: ActivatedRouteSnapshot) {
const tree = {
queryParams: node.queryParams,
params: node.params,
name: node.data.name,
children: node.children.map(createSerializedTree),
firstChild: undefined
};
tree.firstChild = tree.children[0];
return tree;
}
)树上的孩子
let
3)为const _checkIsNodeHasName = (name: string, node: SerializedRouterNode) => {
if (node.name === name) {
return node;
} else if (node.firstChild) {
return _checkIsNodeHasName(name, node.firstChild);
} else {
return undefined;
}
}
export const filterAndMapRoute = (name: string) => {
return (navigationAction$: Observable<RouterNavigationAction<RouterStateUrl>>) => {
return navigationAction$
.map(action => action.payload.routerState)
.filter((state) => !!_checkIsNodeHasName(name, state.root))
.map((state) => _checkIsNodeHasName(name, state.root));
};
};
创建一个函数,过滤并映射到名称与您提供的名称相匹配的第一条路线
@Injectable()
export class ArticlesEffects {
@Effect()
private _onRouteChange$ = this._action$
.ofType(ROUTER_NAVIGATION)
.let(filterAndMapRoute('posts-list'))
.map(/* ... */) // map to whatever action I need
}
现在我可以这样做
firstChild
这或多或少仅仅是一个概念证明,实际上我不仅要检查第一个孩子,还要检查所有孩子。
我首先只使用树的最后一个id
,但有些情况下不起作用,例如,如果您想从这些路线中保存/articles/:id/graph
/articles/:id/table
/ firstChild
,最后一个id
,不会包含2 + 4/2 * 3 = 2+2*3 = 2+6 = 8
,因此需要找到与该名称匹配的第一个子项并映射到该名称(如果没有找到则过滤)。