【问题标题】:Angular 6 Dependency Injection IssueAngular 6 依赖注入问题
【发布时间】:2019-04-02 19:17:33
【问题描述】:

我有一个跨平台的 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();
    }
  }

配置服务初始化正确,但在完成之前,growerServiceFactory 运行并获取未定义的 config.platform,因此即使在将 ConfigService 设置为依赖项之后,它本质上也不会等待 configFactory 解析。我该如何做到这一点?对于这种情况有更好的方法吗?

【问题讨论】:

  • 首先,你为什么使用multi: true?您是否有多个 ConfigServiceUserService 实例?其次,我认为configFactory 应该返回ConfigService 的实例,即它应该是Promise&lt;ConfigService&gt;,并相应地修复。

标签: angular typescript dependency-injection angular6


【解决方案1】:

与其在模块实例化时解决这个问题,不如让服务本身更加灵活?我知道这不能回答你原来的问题,但它可能会解决你的问题。

修改后的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()
       });
    });
  }

不确定您是否将配置服务用于其他目的,但至少在这种情况下可以“跳过”它。

【讨论】:

  • 感谢您的帮助,这是我尝试的第一件事,但看起来基于 Promise 的工厂不适用于常规供应商。我注意到它仅适用于 APP_INITIALIZER 令牌。
  • 本地部署使用什么框架,nativescript?
  • 这是一个基于 Angular 6(typescript) 构建的 Web 应用程序,现在我正在尝试将其转换为使用 Capacitor(Ionic) 用于 ios 本机桥的混合应用程序。
猜你喜欢
  • 2019-03-04
  • 2018-12-03
  • 1970-01-01
  • 2015-11-21
  • 2014-12-27
  • 2015-04-22
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多