共计 2139 个字符,预计需要花费 6 分钟才能阅读完成。
services
currentcy 和 language,都有长久化。base site 没有。Service 里还蕴含通过 url 设置 context 的实现类。总共分 4 组实现。
base-site-initializer.ts(BaseSiteInitializer)
首先,这个类是 Injection Token APP_INITIALIZER
的 provider,在应用程序初始化时执行。
通过构造函数注入的参数,第一个参数来自 facade
文件夹下的 Service 实现,第二个来自 site-context 同级的 config
文件夹。
@Injectable({providedIn: 'root'})
export class BaseSiteInitializer implements OnDestroy {
constructor(
protected baseSiteService: BaseSiteService,
protected configInit: ConfigInitializerService
) {}
initialize
这个办法加载默认值,被 APP_INITIALIZER 的 provider 调用。
initialize(): void {
this.subscription = this.configInit
.getStable('context')
.pipe(// TODO(#12351): <--- plug here explicitly SiteContextRoutesHandler
switchMap(() => this.setFallbackValue())
)
.subscribe();}
setFallbackValue
protected setFallbackValue(): Observable<unknown> {
return this.configInit
.getStable('context')
.pipe(tap((config: SiteContextConfig) => this.setDefaultFromConfig(config))
);
}
这里的 this.configInit.getStable(‘context’) 留待未来钻研。
setDefaultFromConfig
从 config 的默认值设置 Active Base Site:
protected setDefaultFromConfig(config: SiteContextConfig): void {if (!this.baseSiteService.isInitialized()) {
this.baseSiteService.setActive(getContextParameterDefault(config, BASE_SITE_CONTEXT_ID)
);
}
}
咱们能够从调试器里察看一下运行时的行为:
所有的 APP_INITIALIZER provider 被调用,包含本章节正在介绍的 BaseSiteInitializer 的 initialize 办法:
subscribe 最终导致 setDefaultFromConfig 被调用:
此时 context 的所有值都曾经就位了。
currency-state-persistence.service.ts (CurrencyStatePersistenceService)
注入的三个依赖:
export class CurrencyStatePersistenceService {
constructor(
protected statePersistenceService: StatePersistenceService,
protected currencyService: CurrencyService,
protected config: SiteContextConfig
) {}
(1) 来自 state 文件夹
(2) 来自 site-context facade 文件夹下
(3) 就是一个 abstract class,蕴含 urlParameters 属性,类型为 string[]
, 以及 [contextName: string]: string[]
initSync
这个办法调用了 state 文件夹下的 StatePersistenceService,传递 key,state$ 和 onRead 三个参数。
对于 CurrencyService 的 isInitialized 办法,我加了 config.log
, 两次打印都是 true:
onRead
胜利从 localstorage 里读取到了 USD,然而没有进入代码 29 行的 IF 分支,∵ currencyService.isInitialized 返回了 true:
所以这里没有执行 setActive 办法。setActive 办法是通过 url 解析而触发调用的:
总结
本文顺次介绍了 SAP 电商云 Spartacus UI BaseSiteInitializer 类的实现明细。这个类次要作为 APP_INITIALIZER provider 的实现之一,useFactory
的工厂函数,initializeBaseSite
,在这个工厂函数的实现里,通过依赖注入 BaseSiteInitializer 的实例,并调用其私有的 initialize
办法实现默认值的设置。