Angular 5 - 在运行时动态加载模块(在编译时未知) [英] Angular 5 - load modules (that are not known at compile time) dynamically at run-time

查看:29
本文介绍了Angular 5 - 在运行时动态加载模块(在编译时未知)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Angular 5 是否可以加载在编译时未知但在运行时动态加载的模块/组件?

Is it possible for Angular 5 to load modules/components that are not known at compile time, but during runtime dynamically?

我猜这不能使用 webpack 但也许使用 system.js?

I guess this won't work using webpack but maybe using system.js?

整个想法是构建一个基于插件的应用程序,其中单个插件放在插件文件夹中,angular 会自动选择它,而无需重新编译和部署整个 angular 应用程序.插件是独立的功能.当然还有路由导航等.意味着一旦 angular 知道有一个新插件,它应该添加一些动态导航,以便用户能够导航到插件等.

The whole idea is to build a plugin based application where individual plugins are dropped inside a plugin folder, angular will pick it automatically, without having to recompile and deploy the whole angular app. Where plugins are separate pieces of functionalities. Of course there are routes navigation etc. Means that once angular understands there is a new plugin it should add some dynamic navigation so user will be able to navigate to the plugin, etc.

推荐答案

好吧,虽然涉及到复杂性,但您可以尝试一下.我猜这取决于您的代码库.路由器公开 config 属性,保存其当前配置,以及用于重置配置的 resetConfig(routes: Routes) 方法.您可以从那里开始,然后即时添加组件.

Well, while there are complexities involved, you could try it. Depends on your code base I guess. The router exposes config property, holding its current config, and a resetConfig(routes: Routes) method for reseting configuration. You can start from there, and add, say, components on the fly.

不过,组件必须是可访问的.可能是动态创建的,如另一个答案中所述.或者,您的配置可以包含如下内容:

The components do have to be reachable, though. Perhaps dynamically created, as mentioned in the other answer. Alternatively, your config could include something like this:

constructor(private router: Router) {}

private addPlugin(routePath, pluginName, pluginPath) {
    const currentConfig = this.router.config;
    currentConfig.push({
        path: routePath,
        loadChildren: `precompiled-modules/${pluginPath}#${pluginName}`,
    });
    this.router.resetConfig(currentConfig);
}

您必须以某种方式获取 pluginPath 和 pluginName - 也许按照惯例计算它,也许是一个获得此信息的后端助手,也许它的数组已预先配置并已加载或类似.我还假设你会有一个非常好的测试系统,以确保你的插件是兼容的".最后,教 webpack/systemjs 如何准备模块.总而言之,这不是不可能的,但它涉及一些基础工作.

You would have to get the pluginPath and pluginName somehow - maybe calculate it by convention, maybe a lil' backend helper that gets this, maybe have the array of it preconfigured and already loaded or similar. I also assume you would have a really good test system, to make sure your plugins are "compatible". And finally, teach webpack/systemjs how to have the modules ready. All in all, it is not impossible, but it involves some groundwork.

也就是说,Angular 6 即将到来,随之而来的是 Angular Elements.Elements 将提供一种将模块编译为 Web 组件并导出"它们的方法,以便它们可以在任何地方使用(不一定在 Angular 应用程序中).想想 jQuery 插件 - 您需要加载一个基本的 jQuery.min.js,但除此之外,您不再考虑它,您只需使用您的新元素.它与 Angular Elements 类似 - 您导出基本上是 Web 组件的内容.有一个加载器"部分(相当于 jquery.min.js)和您的 Element 包.但是你的组件只是另一个 HTML 节点,有属性、属性、绑定、事件,你不再关心,就像你不关心输入一样.

That said, Angular 6 is around the corner, and with it, Angular Elements. Elements will provide a way to compile your modules as web components and "export" them, so that they can get used anywhere (not necessarily in Angular apps). Think jQuery plugins - there is a base jQuery.min.js you need to have loaded, but apart from that you don't think about it any more, you just use your new elements. It's similar with Angular Elements - you export what is basically a Web component. There is a "loader" part (jquery.min.js equivalent), and your Element bundle. But then your component is just another HTML node, with properties, attributes, bindings, events, you don't care any more, just like you don't about inputs.

等待可能是值得的,请看一看并自行决定.

It might be worth the wait, take a look and decide for yourself.

这篇关于Angular 5 - 在运行时动态加载模块(在编译时未知)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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