1

在我的应用程序中,我不需要在初始化阶段加载模块(通过在 中枚举它们./modules/modules),而是稍后根据某些条件(例如用户授权结果)按需加载。想象一下,我想为用户 A提供计算器模块,为用户 B提供文本编辑器模块。

为简单起见,让我们以样板jssampleModule1示例应用程序为例,并假设它sampleModule2是按需加载的。

所以我从src\modules\modules.js的初始加载序列中删除了模块:

    return [
        require('./baseModule/module'),
        /*require('./sampleModule1/module'),
        require('./sampleModule2/module')*/
    ];

并将控件添加到摘要页面(src\modules\baseModule\landingPage\view.html)以按需加载它们:

<div>
    Congratulations! You are one step closer to creating your next large scale Javascript application!
</div>
<div>
    <select id="ModuleLoader">
        <option value="">Select module to load...</option>
        <option value="./modules/sampleModule1/module">sampleModule1</option>
        <option value="./modules/sampleModule2/module">sampleModule2</option>
    </select>
</div>

然后我修补src\modules\baseModule\module.js以将上下文传递给LandingPageComponent(由于某种原因它不在原始源代码中):

        controller.addRoutes({
            "/" : new LandingPageComponent(context)
        });

最后将加载代码添加到src\modules\baseModule\landingPage\component.js

            $('#ModuleLoader').on('change', function(){
                require([this.value], function(mod){
                    moduleContext.loadChildContexts([mod]);
                    alert('Module enabled. Use can now use it.');
                });
            });

这似乎有效,但这是最好的方法吗?

它是否正确处理上下文加载?

如何防止两次加载相同的模块?

4

2 回答 2

1

您可以通过对更改事件使用命名函数并在执行后取消绑定函数来防止多次加载模块。

于 2013-02-18T16:10:10.350 回答
1

聪明的想法在这里.. 最近几天我也在努力改进 BoilerplateJS 以将模块作为插件延迟加载。我做了类似的事情,你可以在以下位置访问 POC 代码:

https://github.com/hasith/boilerplatejs

在我所做的 POC 中,我试图同时实现“延迟加载”+“可配置 ui”。

  • 每个屏幕(称为应用程序)都是放置在布局上的组件(插件)的集合。这些应用程序定义只是一个 JSON 对象,要么从服务器 API 动态返回,要么静态定义为 JSON 文件(就像它在 POC 中一样)。在 POC 中,应用程序定义存储在“/server/application”中。

  • 现在可以按照约定动态调用这些应用程序。例如,“/##/shipping-app”将在“/server/application”中查找具有相同名称的应用程序定义。

  • 应用程序加载通过我在“/modules/baseModule/appShell”中的一个新组件进行。任何以 '/##/' 开头的内容都将被路由到该组件,然后它将尝试按照约定从“/server/application”文件夹加载应用程序定义。

  • 当“appShell”收到应用程序定义(作为 JSON)时,它也会尝试动态加载其中定义的组件(插件)。这些可插拔组件被放置在 'src/plugins' 中,也将按照约定加载。

示例应用程序定义如下所示:

{
    "application-id" : "2434",
    "application-name" : "Order Application",
    "application-layout" : "dummy-layout.css",

    "components" : [    
        {
            "comp-name" : "OrderDetails",
            "layout-position" : "top-middle"
        },
        {
            "comp-name" : "ShippingDetails",
            "layout-position" : "bottom-middle"
        }
    ]

}

该方法的好处如下:

  • 应用程序接口是组件驱动的,可在运行时配置
  • It is possible that different application definitions are sent to the user depending on the user role, etc (logic in backend)
  • Applications can be created on-the-fly by combining already existing components
  • There is no static code changes needed in the 'framework' either to add new applications or components since loading is based on convention

These are very initial thoughts around. Appreciate any feedback !

于 2013-02-19T14:45:04.020 回答