簡體   English   中英

具有AOT的類型提供者中的角度條件

[英]Angular condition in type provider with AOT

我有一個Angular項目,我用AOT編譯。 我希望能夠注冊根據配置動態解析的ClassProvider 我使用的簡化代碼是這樣的:

const isMock = Math.random() > 0.5;

@NgModule({
  // ...
  providers: [
    { provide: MyServiceBase, useClass: (isMock) ? MyServiceMock : MyService },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

問題是當我用AOT編譯它時,我總是得到相同的服務。 我期望在擊中F5時獲得不同的服務(因為第一行的randomness )。 在沒有AOT的情況下編譯時,它的行為與我期望的一樣。

以下是github上的完整代碼示例: https//github.com/vdolek/angular-test/tree/aot-conditioned-provider-problem 它與ng serveng serve --aot行為不同 - ng serve --aot

我怎樣才能做到這一點? 我知道我可以使用FactoryProvider ,但我會重復的服務依存關系(工廠函數的參數和對財產的DEP FactoryProvider )。

要實現需求的動態特性,您需要通過useFactory屬性使用工廠提供程序

我已經分叉了您的存儲庫, 並按如下方式修改了您的app.module.ts ,以便在AOT中工作。

修改app.module.ts如下

export let myServiceFactory = () => {

  const isMock = Math.random() > 0.5;

  return isMock ? new MyServiceMock() : new MyService();
}; 

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    {provide: MyServiceBase, useFactory: myServiceFactory},
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

在您的服務依賴於其他服務的情況下,您可以使用deps參數來傳遞所需的依賴項。

假設MyServiceBase依賴於兩個服務MyService1MyService2 ......您的工廠函數將如下所示:

export let myServiceFactory = (service1:MyService1, service2:MyService2) => {

  const isMock = Math.random() > 0.5;

  return isMock ? new MyServiceMock(service1, service2) : new MyService(service1, service2);
}; 

並且您的提供商的審核將如下所示

providers: [
    {
       provide: MyServiceBase, 
       useFactory: myServiceFactory,
       deps: [MyService1, MyService2]
    },
]

本指南包含有關在Angular中實現依賴項注入的各種方法的更多詳細信息。

我認為@ jeanpaul-a說除了使用工廠之外別無選擇。 但是管理依賴關系可能不是很干凈。 但你可以使用的是注射器 我會用以下的東西:

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  providers: [
    Dep1Service,
    Dep2Service,
    { provide: MyServiceBase, useFactory: createService, deps: [Injector] }
  ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

export function createService(injector: Injector) {
  const isMock = Math.random() > 0.5;
  if (mock) {
    return new MyService1(injector.get(Dep2Service));
  } else {
    return new MyService2(injector.get(Dep1Service));
  }
}

你還可以做的是將MyServiceBase設置為接口並使用InjectionToken 你會在這里找到一個有效的例子(不過你的班級名稱)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM