简体   繁体   English

如何将动态外部组件加载到Angular应用程序中

[英]How to load dynamic external components into Angular application

I'm facing a problem with Angular application. 我遇到了Angular应用程序的问题。

I would like to have an angular application written in Typscript build with (aot). 我想用(aot)的Typscript构建一个角度应用程序。

The aim is to display a user dashboard with some widgets. 目的是显示带有一些小部件的用户仪表板。 A widget is an angular component. 小部件是角度组件。

My app comes with some embedded widgets. 我的应用程序附带了一些嵌入式小部件。 But widgets should be extended by something like a market place; 但小部件应该通过像市场这样的东西来扩展; or created manually. 或手动创建。

The market should download files (js/ts/bunlde..??) into a specific folder. 市场应该将文件(js / ts / bunlde .. ??)下载到特定的文件夹中。

Then my app should be able to load the new widgets (= ng component) and instanciate them. 然后我的应用程序应该能够加载新的小部件(= ng组件)并实例化它们。

My folder structure (production) 我的文件夹结构(制作)

  |- index.html
  |- main.f5b448e73f5a1f3f796e.bundle.js
  |- main.f5b448e73f5a1f3f796e.bundle.js.map
  |- .... (all other files generated)
  |- externalWidgets
      |- widgetA
            |- widjetA.js
            |- widjetA.js.map
            |- assets
                 |- image.png
      |- widgetB
            |- widjetB.ts
            |- widjetB.html
            |- widjetB.css

Then when loading the user page, the database say that there is a widgetA. 然后在加载用户页面时,数据库说有一个widgetA。 So the aim is to dynamically load files and instanciate included component. 因此,目标是动态加载文件和instanciate包含的组件。

I've tried many solutions, using "require" and "System.import" but both fails when the path to load is dynamically generated. 我尝试过很多解决方案,使用“require”和“System.import”,但是当动态生成加载路径时,两者都失败了。

Is this should be possible ? 这应该是可能的吗? I can change my code structure; 我可以改变我的代码结构; change external widgets.. (for example widgetB is not yet transpiled,...) 更改外部小部件..(例如,widgetB尚未转换,...​​)

In fact I'm looking for a "plugin system" with an Angular4/webpack application. 事实上,我正在寻找一个带有Angular4 / webpack应用程序的“插件系统”。

I'm doing exactly the same. 我做的完全一样。 And I explain the details in this talk at NgConf. 我在NgConf的演讲中解释了细节。

The first thing to understand is that Webpack cannot dynamically load modules that are unknown during build time. 首先要了解的是Webpack无法动态加载构建期间未知的模块。 This is inherent to the way Webpack builds dependency tree and collects modules identifiers during build time. 这是Webpack构建依赖关系树并在构建期间收集模块标识符的方式所固有的。 And it's perfectly fine since Webpack is a modules bundler, not modules loader. 它完全没问题,因为Webpack是一个模块捆绑器,而不是模块加载器。 So you need to use a module loader and the only viable option now is SystemJS. 所以你需要使用模块加载器,现在唯一可行的选择是SystemJS。

Then, each plugin should be packaged as a module and all exported components should be added to the entryComponents of that module. 然后,应将每个插件打包为一个模块,并将所有导出的组件添加到该模块的entryComponents中。

During runtime, you will load that module to get access to the components declared inside if it. 在运行时,您将加载该模块以访问内部声明的组件(如果它)。 You don't really need a module but that's a unit of packaging in Angular so you can't avoid using it. 你真的不需要一个模块,但这是Angular中的一个包装单元,所以你不能避免使用它。 Now, once you get a module, you have to options depending on whether the module is built using AOT or not. 现在,一旦你得到一个模块,你必须选择,具体取决于模块是否是使用AOT构建的。

If it's built using AOT, you just get the exported factory class from the module and create a module instance: 如果它是使用AOT构建的,您只需从模块中获取导出的工厂类并创建模块实例:

System.import('path/to/module').then((module)=>{
    const moduleFactory = module.moduleFactoryClassName;
    const moduleRef = moduleFactory.create(this.parentInjector);
    const resolver = moduleRef.componentFactoryResolver;
    const compFactory = resolver.resolveComponentFactory(AComponent);
}

If it's not built using AOT, you have to compile it using JIT compiler: 如果它不是使用AOT构建的,则必须使用JIT编译器进行编译:

System.import('path/to/module').then((module)=>{
    const moduleFactory = this.compiler.compileModuleSync(module.moduleClassName);
    const moduleRef = moduleFactory.create(this.parentInjector);
    const resolver = moduleRef.componentFactoryResolver;
    const compFactory = resolver.resolveComponentFactory(AComponent);
}

Then you can add dynamic components wherever you want using techniques described in this article: Here is what you need to know about dynamic components in Angular 然后,您可以使用本文中介绍的技术在任何位置添加动态组件: 以下是您需要了解的有关Angular中动态组件的信息

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

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