Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular NgRx:CustomRouterStateSerializer()被多次调用_Angular_Ngrx_Ngrx Store_Ngrx Router Store - Fatal编程技术网

Angular NgRx:CustomRouterStateSerializer()被多次调用

Angular NgRx:CustomRouterStateSerializer()被多次调用,angular,ngrx,ngrx-store,ngrx-router-store,Angular,Ngrx,Ngrx Store,Ngrx Router Store,我已经用常用的方法()为我的Angular项目实现了一个NgRx路由器存储 我的“问题”是,当通过单击组件的相应html元素触发routerLink时,我的CustomRouterStateSerializer的serialize方法似乎被调用多次 您将在上找到以下描述的最小示例应用程序 我的实施 这是我的router.reducer.ts文件,其中包含RouterStateUrl接口和序列化程序类: 导出接口RouterStateUrl{ url:string; 查询参数:参数; 参数:参数

我已经用常用的方法()为我的Angular项目实现了一个NgRx路由器存储

我的“问题”是,当通过单击组件的相应html元素触发routerLink时,我的
CustomRouterStateSerializer
的serialize方法似乎被调用多次

您将在上找到以下描述的最小示例应用程序


我的实施

这是我的
router.reducer.ts
文件,其中包含RouterStateUrl接口和序列化程序类:

导出接口RouterStateUrl{
url:string;
查询参数:参数;
参数:参数;
随机数;
}
导出类CustomRouterStateSerializer实现RouterStateSerializer{
序列化(routerState:RouterStateSnapshot):RouterStateUrl{
常量{url,根:{queryParams}}=routerState;
//随机数,以便以后能够将控制台输出与路由器状态相匹配(使用NgRx Store DevTools)
const random=Math.random();
warn(`CustomRouterStateSerializer被${url}调用,random:${random}`);
let状态:ActivatedRouteSnapshot=routerState.root;
while(state.firstChild){
state=state.firstChild;
}
const{params}=状态;
返回{url,queryParams,params,random};
}
}
这是我的
app.module.ts
文件:

/*[…]*/
进口:[
/*[...],*/
StoreModule.forRoot(减速器、{
变质还原剂,
运行时检查:{
strictStateImmutability:true,
严格的不可更改性:true
}
}),
StoreDevtoolsModule.instrument({maxAge:25,logOnly:environment.development}),
EffectsModule.forRoot([AppEffects]),
StoreRouterConnectionModule.forRoot({
序列化程序:CustomRouterStateSerializer,
navigationActionTiming:navigationActionTiming.PostActivation,
}),
]
/*[...]*/

详细描述和输出

假设我的应用程序当前显示一些项目的概述(url:/projects),routerLink触发切换组件以显示作业概述(url:/jobs)。控制台将打印三条消息:

  • CustomRouterStateSerializer由/projects调用,随机:0.0896547559010431

  • CustomRouterStateSerializer由/jobs调用,随机:0.766202575297263

  • CustomRouterStateSerializer由/jobs调用,随机:0.079191760163307328

NgRx商店开发工具显示了预期的几个操作:

@ngrx/路由器存储/请求

router: {
    state: {
        url: '/projects',
        queryParams: {},
        params: {},
        random: 0.31957045879116797
    },
    navigationId: 2
}
@ngrx/路由器存储/导航

router: {
    state: {
        url: '/jobs',
        queryParams: {},
        params: {},
        random: 0.7662025752972623
    },
    navigationId: 3
}
@ngrx/路由器存储/导航

router: {
    state: {
      url: '/jobs',
      queryParams: {},
      params: {},
      random: 0.7662025752972623
    },
    navigationId: 3
}
如您所见,
@ngrx/路由器存储/导航
@ngrx/路由器存储/导航
的状态相同。此外,它们的随机数与第二个控制台输出相同。
@ngrx/router store/request
的随机数属于旧项目视图的状态


NgRx存储开发工具的输出似乎与预期一致。但是我不明白其他控制台输出是在什么时候调用serialize方法的。在任何状态下,我都找不到第一个和第三个控制台输出的任何随机数。现在我在问自己,我是否犯了错误(实现了一些东西),或者这只是正常的行为(但为什么?)。也许你们中的一些人可以告诉我。

我尝试了一些东西,但最后它帮助我们了解了
@ngrx/router store
的源代码。 该模块的基本功能是监听所有路由器事件和调度操作。重要的代码如下:

但是我不明白其他控制台输出是在什么时候调用serialize方法的

您可以在这里看到有三种情况可以调用
serialize()

  • 在导航开始时(直接)
  • NavigationEnd
    (通过
    dispatchRouterNavigation()
    dispatchRouterNavigated()
    方法)
  • 在<代码>路线识别<代码>(通过<代码>调度路线激活()
每个事件分别调用
serialize()
,以避免派生状态:路由器是路由器状态的来源,它可以在任何给定时间更改。 因此,当需要序列化状态时,它将不会存储在某个位置,而是每次新计算。 这就是函数被多次调用的原因。但是,由于序列化程序函数应该是纯函数,因此这根本不是问题,而是设计的一部分

在任何状态下,我都找不到第一个和第三个控制台输出的任何随机数

只会在
导航
取消
错误
上将路由器状态放入存储,但不会在
请求
导航
上。 这意味着,您将在商店中看到的唯一随机数是源自
导航操作的随机数。
所有其他的都只是“在路上”而已

现在我在问自己,我是否犯了错误(实现了一些东西),或者这只是正常的行为(但为什么?)


您的实现看起来不错,您可以放心了:这是正常的和预期的行为!我添加了一个关于StackBlitz的最小示例: