将动态条目组件传递到模块中,然后再将它们传递到另一个模块中的角 [英] Angular passing dynamic entry components into module and then passing them again into another module

查看:50
本文介绍了将动态条目组件传递到模块中,然后再将它们传递到另一个模块中的角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为组件库制作模态组件.我在组件库中使用了一个第三方模型库.一个主要功能是能够通过服务传递组件并将其动态添加到模式中.

I'm making a modal component for a component library. I made a 3rd party modal library that I'm using within my component library. A main feature is being able to pass a component via a service and dynamically adding it to the modal.

我的模态库有一个静态方法,允许您将组件添加到模块的入口组件中.看起来像:

My modal lib has a static method that allows you to add your component to the module's entry components. It looks like:

export class A11yModalModule {
  static withComponents(components: any[]) {
    return {
      ngModule: A11yModalModule,
      providers: [{
        provide: ANALYZE_FOR_ENTRY_COMPONENTS,
        useValue: components,
        multi: true
      }]
    };
  }
}

很酷,行得通.像这样导入模块时,可以将组件传递给它: A11yModalModule.withComponents([ModalContentComponent])

Cool, that works. I can pass components into it when I import the module like this: A11yModalModule.withComponents([ModalContentComponent])

当我将其抽象出另一个级别时,就会发生我的问题.因此,现在有了2个模块,而不是2个模块.我需要像上面一样将一个组件从lib Consumer的模块传递到我的组件模块,然后传递给模式模块.

My problem occurs when I abstract this out another level. So now instead of 2 modules I have 3. I need to pass a component like I did above from the lib consumer's module, to my component module, and then into the modal module.

如何将组件从lib模块传递到模式模块?

How can I pass components from the lib module to the modal module?

我想我越来越近了.这是我的3个模块

I think I'm getting close. Here are my 3 modules

// app module
@NgModule({
  declarations: [AppComponent, ModalContentComponent],
  imports: [
    LibModalModule.withComponents([ModalContentComponent])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }



// lib module
@NgModule({
  imports: [CommonModule],
  declarations: [LibModal],
  providers: [LibModalService],
  exports: []
})
export class LibModalModule {
  static withComponents(components: any[]) {
    return {
      ngModule: LibModalModule,
      imports: [CommonModule, A11yModalModule.withComponents(components)]
    };
  }
}



// a11y modal module
@NgModule({
  imports: [CommonModule],
  declarations: [ModalComponent],
  exports: [],
  providers: [ModalService, DomService],
  entryComponents: [ModalComponent]
})
export class A11yModalModule {
  static withComponents(components: any[]) {
    return {
      ngModule: A11yModalModule,
      providers: [{
        provide: ANALYZE_FOR_ENTRY_COMPONENTS,
        useValue: components,
        multi: true
      }]
    };
  }
}

推荐答案

withComponents 方法应返回 ModuleWithProviders 对象,该对象只是包装也包含提供者的模块的包装.

withComponents method should return ModuleWithProviders object which is just wrapper around a module that also includes the providers.

它不能具有 imports 属性或其他属性,因为它不理解这些属性.这是来自angular的摘录负责从 ModuleWithProviders 中读取元数据的源代码:

It can't have imports property or something else because it doesn't understand those properties. Here's an excerpt from angular source code that is responsible from reading metadata from ModuleWithProviders:

else if (importedType && importedType.ngModule) {
  const moduleWithProviders: ModuleWithProviders = importedType;
  importedModuleType = moduleWithProviders.ngModule;
  if (moduleWithProviders.providers) {
    providers.push(...this._getProvidersMetadata(
        moduleWithProviders.providers, entryComponents,
        `provider for the NgModule '${stringifyType(importedModuleType)}'`, [],
            importedType));
    }
}

我们可以看到,角度编译器从将通过withComponents方法返回的对象中获取提供程序.

As we can see angular compiler takes providers from the object that will returned in withComponents method.

因此,为了合并模块,您可以使用方法(在 LibModalModule.withProviders 中提供 ANALYZE_FOR_ENTRY_COMPONENTS )或重用 A11yModalModule.withComponents 喜欢:

So, in order to merge your modules you can either use your approach(provide ANALYZE_FOR_ENTRY_COMPONENTS in LibModalModule.withProviders) or reuse A11yModalModule.withComponents like:

@NgModule({
  imports: [CommonModule, A11yModalModule],
  providers: [LibModalService],
  exports: []
})
export class LibModalModule {
  static withComponents(components: any[]) {
    return {
      ngModule: LibModalModule,
      providers: A11yModalModule.withComponents(components).providers
    };
  }
}

(已通过AOT测试)

还必须将 A11yModalModule 导入到 LibModalModule 中(而且我想您将使用 A11yModalModule 中定义的> ModalService 和 DomService ).这是因为angular包含了根模块注入器中传递模块的所有提供程序.

Also A11yModalModule has to be imported in LibModalModule if we want its providers to be included in our root module injector (And i suppose you're going to use ModalService and DomService that are declated in A11yModalModule). The reason of this is that angular includes all providers from transitive module in root module injector.

另请参阅:

您一直想了解的内容角依赖注入树

这篇关于将动态条目组件传递到模块中,然后再将它们传递到另一个模块中的角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆