我有一个跨平台的Angular应用程序,我需要检查该应用程序正在运行的平台,然后根据此信息决定注入服务。这是我的结构:
@NgModule({
providers: [
ConfigService,
{
provide: APP_INITIALIZER,
useFactory: configFactory,
deps: [ConfigService],
multi: true
},
{
provide: UserService,
useFactory: userServiceFactory,
deps: [
ConfigService
],
multi: true
},
],
bootstrap: [AppComponent]
})
export class AppModule { }
配置工厂返回Promise:
export function configFactory(configService: ConfigService): () => Promise<any> {
return (): Promise<any> => {
return new Promise(resolve => {
Device.getInfo().then(info => {
configService.platform = info.platform; // it either ios or web
});
});
}
}
需要configService.platform来决定UserService提供程序,因此我拥有工厂方法:
const userServiceFactory = (configService: ConfigService): any => {
if(configService.platform === 'ios') {
return new UserServiceDevice()
} else {
return new UserWebServiceWeb();
}
}
config服务正确初始化,但是在它完成之前,growerServiceFactory运行并获得未定义的config.platform,因此,即使将ConfigService设置为依赖项,它实际上也不会等待configFactory解析。我该如何实现?对于这种情况有更好的方法吗?
答案 0 :(得分:0)
与其在模块实例化时解决这个问题,不如使服务本身更灵活?我知道这不能解决您的原始问题,但可以解决您的问题。
修改后的UserService:
class PlatformAgnosticUserService implements IUserService {
private service: IUserService;
constructor(
private _PLAT : Platform,
private mobileUserService: MobileUserService,
private webUserService: WebUserService
) {
if (this._PLAT.is('ios') || this._PLAT.is('android'))
{
this.service = mobileUserService;
}
else
{
this.service = webUserService;
}
}
userCreate(param: any) {
this.service.userCreate(param);
}
}
我知道那不是很好,但是这是我能想到的最好的了。
下面的旧答案
我认为您可能使事情复杂化了。为什么不简化为这样:
@NgModule({
providers: [
{
provide: UserService,
useFactory: userServiceFactory,
deps: [],
multi: true
},
],
bootstrap: [AppComponent]
})
export class AppModule { }
这:
const growerServiceFactory = (configService: ConfigService): () => Promise<any> => {
return (): Promise<any> => {
return new Promise(
resolve => {
Device.getInfo().then(info => {
return new UserServiceDevice();
},
() => {
return new UserWebServiceWeb()
});
});
}
不确定是否将config服务用于其他任何用途,但至少在这种情况下可以“跳过”。