简体   繁体   English

Angular2:从给定文件夹动态加载模块

[英]Angular2: Loading modules dynamically from a given folder

app
 |-plugins
       |-plugin1
           |-config.json
           |-plugin1.module.ts
           |-plugin1.component.ts

       |-plugin2
           |-config.json
           |-plugin2.module.ts
           |-plugin2.component.ts

As you can see above, I have "app/plugins" folder, which contains plugins. 如上所示,我有“app / plugins”文件夹,其中包含插件。 Each plugin will contain one "config.json" file which will tell some configuration including - 每个插件将包含一个“config.json”文件,它将告诉一些配置,包括 -

{
   path: "feature1",
   moduleFile: "feature1.module",
   moduleClassName: "Feature1Module"
}

So what I want is, before application bootstrap it will scan the "app/plugins" folder and load all plugin configurations, and lazily register all module routes. 所以我想要的是,在应用程序引导之前,它将扫描“app / plugins”文件夹并加载所有插件配置,并懒惰地注册所有模块路由。 For above example the route will be 对于上面的例子,路线将是

{
     path: "feature1",
     loadChildren: "app/plugins/plugin1/plugin1.module#Plugin1Module"
}

That way, we can drop new plugin into plugin folder and refresh the application, and our newly dropped plugin is up and running. 这样,我们可以将新插件放入插件文件夹并刷新应用程序,我们新删除的插件已启动并运行。

Anyone knows how can I achieve this? 谁知道我怎么能做到这一点?

NOTE: I am on angular2 latest(2.1.0) 注意: 我在angular2最新(2.1.0)

I'm looking for the same behavior than the one you're describing and I think I've found how to do it, thanks to this github issue : Lazy loading components without Route 我正在寻找与你描述的行为相同的行为,我想我已经找到了如何做到这一点,这要归功于这个github问题: 没有路由的延迟加载组件

Here is the code I've written to do it : plunker here 这是我写的代码: plunker here

  • First : dynamic.module.ts, the dynamically loaded module and its component 首先:dynamic.module.ts,动态加载的模块及其组件

     import { Component, NgModule } from '@angular/core' @Component({ selector: 'my-test', template: `<h1>html template of TestComponent from DynamicModule</h1>` }) export class TestComponent { } @NgModule({ declarations: [TestComponent], exports: [TestComponent] }) export class DynamicModule { } 
  • Second : here is the component which dynamically loads module when you give it the module path. 第二:这是在给出模块路径时动态加载模块的组件。

     import { Component, ViewContainerRef, Compiler, ComponentFactory, ComponentFactoryResolver, ModuleWithComponentFactories, ComponentRef, ReflectiveInjector, SystemJsNgModuleLoader } from '@angular/core'; class ModuleNode { modulePath: string; componentName: string; } @Component({ moduleId: module.id, selector: 'widgetContainer', templateUrl: './widgetContainer.component.html' }) export class WidgetContainerComponent { widgetConfig: string; module: ModuleNode; cmpRef: ComponentRef<any>; constructor(private widgetService: WidgetLoader, private viewref: ViewContainerRef, private resolver: ComponentFactoryResolver, private loader: SystemJsNgModuleLoader, private compiler: Compiler){} openWebApp(menu:any) { this.loader.load(menu.modulePath) // load the module and its components .then((modFac) => { // the missing step, need to use Compiler to resolve the module's embedded components this.compiler.compileModuleAndAllComponentsAsync<any>(modFac.moduleType) .then((factory: ModuleWithComponentFactories<any>) => { return factory.componentFactories.find(x => x.componentType.name === menu.componentName); }) .then(cmpFactory => { // need to instantiate the Module so we can use it as the provider for the new component let modRef = modFac.create(this.viewref.parentInjector); this.cmpRef = this.viewref.createComponent(cmpFactory, 0, modRef.injector); // done, now Module and main Component are known to NG2 }); }); } ngOnDestroy() { if (this.cmpRef) { this.cmpRef.destroy(); } } 

    } }

What do you think about that? 你觉得怎么样? Does it help? 有帮助吗? Thanks a lot for your feedback. 非常感谢您的反馈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM