场景如下:
1.应用程序具有根模块,它的构造函数解析了一个承诺并返回一个常量。
@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 的全局常量,并作为参数传递给工厂函数,使用该常量构造注入器令牌并在引导时分配值 null(初始状态(。
export const SAMPLE_GLOBAL_CONSTANT = {
DATA: null // Initial State
}
4.当promise从步骤1中解析时,我捕获了Promise返回的常量值,并辅以这个声明的全局常量,因为它是一个常量,显然正在通过应用程序进行更新和可用。
此外,角度文档指出 useFactory 提供程序懒惰地创建其值,据我了解,它将在注入时创建。如果是这样,则在代码注入我的注入令牌时,全局常量将更新。注入器令牌仍然具有空值。
问题 1.有没有办法使用更新的本地状态调用提供程序工厂函数,以便我的注入器令牌将收到值?
问题 2.当我使用全局常量时,它使代码工作,但它不是松散耦合的,这也使单元测试变得困难。是否有任何替代方法来消耗接收常量并在代码中使用它,以便松散耦合?
我解决的一种方法是使用 RxJS 的重播主题。 首先,这是一个包裹在承诺中的帖子消息服务。因此,一旦发送了消息(从另一个应用程序(并且承诺得到解决(在使用应用程序中(,就必须有一种方法来保存该发送数据以在整个应用程序中使用它。
使用缓冲区值为 1 的重播主题(这意味着将最近的一个值重播到订阅(会在解决上述方案后生成最后一个捕获的值。
然后将获得的数据传递给订阅中的 Angular 服务,使其在整个应用程序中可用。
现在,这使得角度服务而不是全局常量中的所需数据变得容易,这使得单元测试变得容易。
注意:工厂提供程序无法解决此问题,因为 angular 尝试在启动发生之前解析,默认为初始化值(在我的情况下,它是空值(。所以这是行不通的。
为什么不是异步主题?
由于异步主题仅在完成信号后被触发,并且我正在解决的业务案例在声明完成信号之前确实有中间工作要做。它没有解决目的。