场景如下:
1。应用程序具有根模块,其构造函数可解决Promise并返回常量。
@NgModule({
....,
providers : [
...
{
provide: SAMPLE_INJECTOR_TOKEN,
useFactory: sampleFactoryFn(SAMPLE_GLOBAL_CONSTANT.DATA)
}
]
})
export class AppModule {
constructor() {
// To be clear: This code runs on window.onLoad(). window argument is actually window object
setupPromiseAPI(window).then(data => {
SAMPLE_GLOBAL_CONSTANT.DATA = data; // Once promise resolves this gets expected value. [ Step 3 ]
}).catch({
...
})
}
2。由于此值既是对象,又是运行时可用的对象,因此我使用“ useFactory”创建了一个注入令牌,并在模块级别进行了注册。
// Injector Token
export SAMPLE_INJECTOR_TOKEN = new InjectionToken<CustomDataType>('SampleInjectorToken');
// Factory Function
export function sampleFactoryFn(data: CustomDataType) {
return (/* No deps to be passed */): CustomDataType => data; // simply return what ever it received.
}
3。我创建了一个全局常量,将其初始化为null并将其作为参数传递给factory函数,使用该angular构造Injector Token并在启动时分配值null(初始状态)。
export const SAMPLE_GLOBAL_CONSTANT = {
DATA: null // Initial State
}
4。当Promise从第1步中解决后,我将捕获从Promise返回的常量值,并辅助使用此声明的Global Constant作为其常量,很显然,该常量正在通过应用程序进行更新和使用。
此外,角度文档指出useFactory provider会延迟创建其值,据我了解,它将在注入时创建。如果是这样,则在时间代码注入我的注入令牌时,全局常量将被更新。喷油器令牌仍然为空。
问题1。有没有办法用更新的本地状态调用提供程序工厂功能,以便我的注射器令牌已收到值?
第二季度。在使用全局常量时,它使代码有效,但耦合程度不高,这也使单元测试变得困难。有没有其他选择可以使用接收到的常量并在代码中使用它,以使其松散耦合?
答案 0 :(得分:1)
我解决的一种方法是使用RxJS中的Replay Subject。首先,这是一个包装在promise中的postMessage服务。因此,一旦(从另一个应用程序)发送了消息并(在使用应用程序中)解决了诺言,就必须有一种保留发送数据的方法,以便在整个应用程序中使用它。
使用缓冲值为1的重播主题,这意味着将最近的一个值重播到订阅中,一旦解决了上述情况,就会产生最后捕获的值。
然后将获得的数据订阅中的数据传递给Angular Service,使其在整个应用程序中可用。
现在,这使得需要使用角度服务而不是全局常数的数据,这使得单元测试变得容易。
注意:,工厂提供者无法解决这种情况,因为angular会在启动发生之前尝试解决,该问题默认为初始化值(在我的情况下为null)。所以这行不通。
为什么不同步主题?
由于异步主体仅在完成信号后被解雇,因此我要解决的业务案例在声明完成信号之前确实有中间工作要做。它没有解决目的。