angular - 可配置的 Angular 9 模块

标签 angular typescript dependency-injection module

我想创建可配置的 Angular 9 模块,并启用 IVY 和 AOT。

IVY and AOT on by default in current version of Angular:

npx @angular/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="43202f2a037a6d736d75" rel="noreferrer noopener nofollow">[email protected]</a> new ng-modules --style=scss --routing=false

在最简单的场景中,它必须提供可按名称配置的单个有状态服务:

计数器.module.ts

@Injectable()
export class CounterService {
  private counter = 0;
  shot() {
    return this.counter++;
  }
}

@NgModule()
export class CounterModule {
  static withConfig(name: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: [{
        provide: name,
        useClass: CounterService
      }]
    };
  }
}

app.module.ts

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CounterModule.withConfig('main.CountService'),
    CounterModule.withConfig('integration.CountService'),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'ng-modules-shots';
  constructor(
    @Inject('main.CountService') counter: CounterService,
  ) {
    this.title = '' + counter.shot();
  }

}

此时一切正常。但如果我想在CounterModule.withConfig中添加任何逻辑:

计数器.module.ts

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    const counterProviderToken = name ? name : CounterService;
    return {
      ngModule: CounterModule,
      providers: [{
        provide: counterProviderToken,
        useClass: CounterService
      }]
    };
  }
}

我收到错误:

ERROR in src/app/app.module.ts:11:16 - error NG1010: Value at position 1 in the NgModule.imports of AppModule is not a reference: [object Object]

我能做什么呢?以某种方式修复它吗?也许还有另一种方法来制作可配置模块?

最佳答案

当前有一个限制,即函数中只有一条语句。因此,如果您想向其中添加任何逻辑并保持 AOT 工作,则应将其放置在该语句内。

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: [{
        provide: name ? name : CounterService,
        useClass: CounterService
      }]
    };
  }
}

不过,您可以使用函数在此模块中生成提供程序:

...
@NgModule()
export class CounterModule {
  static withConfig(name?: string): ModuleWithProviders {
    return {
      ngModule: CounterModule,
      providers: this.generateProviders(name)
    };
  }

  private static generateProviders(name?: string): Provider[] {
    const counterProviderToken = name ? name : CounterService;
    return [{
      provide: counterProviderToken,
      useClass: CounterService
    }]
  }
}

关于angular - 可配置的 Angular 9 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60692975/

相关文章:

javascript - 如何在 Angular Typescript 中访问此关键字

java - spring boot + angular 2部署

typescript - 输入自定义指令

java - 构造函数进行 Spring 依赖注入(inject) - 创建 bean 时出错,由 : java. lang.InknownClassChangeError 引起

c# - “StructureMap.ObjectFactory”已过时

java - 使用 Dagger 2 的 Android 依赖注入(inject)

javascript - 当滚动太快时,白屏出现棱 Angular

typescript - 在 router.ts 中访问 Vuex store 模块的状态

javascript - 历史前进/后退按钮不适用于 Angular 2 路由器

css - Angular scss 不适用于 ngx-datatable