SAP 电商云 Spartacus UI SiteContextRoutesHandler 的技术实现明细介绍

site-context-routes-handler.ts (SiteContextRoutesHandler)

三个依赖:

image

site context state 和 url 之间存在双向同步关系。

init

init() {
    
    
    this.router = this.injector.get<Router>(Router);

    this.location = this.injector.get<Location>(Location);
    const routingParams = this.siteContextParams.getUrlEncodingParameters();

    if (routingParams.length) {
    
    
      this.setContextParamsFromRoute(this.location.path(true));
      this.subscribeChanges(routingParams);
      this.subscribeRouting();
    }
  }

上述代码,调用 getUrlEncodingParameters 获取参数列表:

然后从 this.location.path 得到当前浏览器地址栏里的 url,从 url /electronics-spa/en/USD 里提取出参数。

setContextParamsFromRoute

从 url 里解析参数,然后更新 site context state

解析出的参数是一个 JSON 对象:

根据参数名称,从 service map 里获取对应的 service 实例,然后调用 setValue 方法。

还是 facade 层的 setActive 方法:

最后在 reducer 里返回一个新的状态(有限状态自动机):

注意 callstack:

subscribeChanges

site context 发生变化之后,我们需要采用编程的方式,更新浏览器地址栏里的 url.

例子:当我从 language 下拉菜单里将语言从英语更改到中文时,断点立即触发:

此时 router url 里已经出现了 zh,这个值是什么时候写入的?

这行代码 this.location.replaceState(serialized); 单步执行之后,地址栏立即出现了zh:

语言发生变化之后,如何同步到浏览器地址栏的 url 字段?

切换成中文后,this.router.url 片段里,已经出现了 zh,这是一个 get 实现:

调试器显示,这个 get 的执行根本还没结束:

上图是 Angular 框架代码,url 是通过 this.serializeUrl(this.currentUrlTree) 动态计算出来的。

router 的 urlSerializer 是我们动态注入进去的:

这里就开始执行我们自己的业务逻辑了:

params 参数为空:

segment,query 和 fragment 全部为空:

然后再从 urlEncodingParameters 里依次将 baseSite,language 和 currency 最新的参数值读取出来:

既然传进来的 params 里没有数据,就调用 SiteContextParamsService 读取参数值:

现在调用的就是 services 文件夹下的实现,之前已经了解过了:

从 service map 里读取数据:

image

所以 router 最后的值进行了更新:electronics-spa/zh/USD/

猜你喜欢

转载自blog.csdn.net/i042416/article/details/125786283