首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从模块中获取角度为8的注入器

从模块中获取角度为8的注入器
EN

Stack Overflow用户
提问于 2019-07-16 11:09:43
回答 1查看 4.6K关注 0票数 2

问题:

我正在为非路由模块的角度设置延迟加载。在第7版中,我使用了NgModuleFactoryLoader及其函数load来延迟加载模块并获得模块的第一个入口点(用例中的服务)

代码语言:javascript
复制
this.loader.load('path-to-module')
  .then(factory => {
    const module = factory.create(this._injector);
    return module.injector.get(EntryService);
  });

但是在角8中,NgModuleFactoryLoader是不推荐的,所以我不得不以这种方式加载模块:

代码语言:javascript
复制
import('path-to-module')
  .then(m => m.MyModule)
  .then(myModule => {
    ...
});

这里的问题是,我无法在新的延迟加载中检索工厂和提供者(常春藤的想法之一--没有工厂)。

我已经尝试过的:

第一种解决方案(只使用JIT编译器,这不适合我们,因为我正在使用AOT编译器进行prod)

代码语言:javascript
复制
import('path-to-module')
  .then(m => m.MyModule)
  .then(myModule => {
    return this._compiler.compileModuleAsync(myModule)
      .then(factory => {
        const module = factory.create(this._injector);
        return module.injector.get(EntryService);
      });
});

第二种解决方案(脏和未完全检查)。它使用的是ngInjectorDef,这是常春藤的新特性,目前还没有任何描述的API ):

代码语言:javascript
复制
import('path-to-module')
  .then(m => m.MyModule)
  .then(myModule => {
    const providers = myModule['ngInjectorDef'].providers; // Array<Providers>
    ... find EntryService in providers
});

ngInjectorDef -是一个静态模块类属性,由角添加,并具有属性工厂、提供程序和导入。

来源:

EN

回答 1

Stack Overflow用户

发布于 2019-07-23 21:04:07

我不会说访问ngInjectorDef属性是“肮脏的黑客”。是的,在任何地方都没有记载,因为,正如伊戈尔·米纳尔所说,常春藤在角度8中是可选的预览版,但许多私人功能已经在维克多·萨金的一些文章中提到过,比如directiveInject

不应在providers属性中搜索服务。假设有20+提供程序,而且在生产过程中,EntryService名称也将缩小为tk

如果您使用常春藤-有一个名为createInjector的私有函数,它接受模块构造函数作为参数。

代码语言:javascript
复制
@Injectable()
export class EntryService {
  public logFromEntryService(): void {
    console.log('Logging from EntryService...');
  }
}

@NgModule({
  providers: [EntryService]
})
export class EntryModule {
  public static getEntryService: () => EntryService = null;

  constructor(injector: Injector) {
    EntryModule.getEntryService = () => injector.get(EntryService);
  }
}

假设您有这样的代码,让我们使用一个动态导入来加载这个EntryModule

代码语言:javascript
复制
import { ɵcreateInjector as createInjector } from '@angular/core';

export class AppComponent {
  constructor(private injector: Injector) {
    this.loadEntryModule();
  }

  private async loadEntryModule(): Promise<void> {
    const { EntryModule } = await import('./entry.module');
    createInjector(EntryModule, this.injector);
    EntryModule.getEntryService().logFromEntryService();
  }
}

createInjector用于实例化EntryModule,在实例化之后- getEntryService静态方法并不等于null

我们还可以公开injector属性,例如:

代码语言:javascript
复制
public static injector: Injector = null;

constructor(injector: Injector) {
  EntryModule.injector = injector;
}

这可能被视为一个服务定位器,这是一种反模式。但取决于你!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57055895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档