使用RequireJS延迟加载AngularJS模块

时间:2013-10-02 09:39:35

标签: angularjs requirejs

感谢伟大的article from Dan Wahlin,我设法实现了Angular的控制器和服务的延迟加载。但是,对于延迟加载独立模块似乎没有一种干净的方法。

为了更好地解释我的问题,假设我的应用程序结构如下,没有RequireJS:

// Create independent module 'dataServices' module with 'Pictures' object
angular.module("dataServices", []).factory("Pictures", function (...) {...});

// Create 'webapp' ng-app, with dependency to 'dataServices', defining controllers
angular.module("webapp", ['dataServices'])
.controller("View1Controller", function (...) {...})
.controller("View2Controller", function (...) {...});

以下是Plunker中带有RequireJS的示例应用程序:
http://plnkr.co/aiarzVpMJchYPjFRrkwn

问题的核心是Angular不允许在ng-app后实例化时添加依赖项。因此,我的解决方案是使用angular.injector来检索要在Picture中使用的View2Controller对象的实例。请参阅js/scripts/controllers/ctrl2.js文件。

这给我带来了两个问题:

  1. 注入的服务在angular之外运行,因此所有异步调用必须以$ scope结尾。$ apply()
  2. 凌乱的代码,其中某些对象可以使用标准角度语法注入,而其他对象则需要明确使用注入器。
  3. 你们有没有想过如何使用RequireJS延迟加载独立模块,并以某种方式将此模块挂钩成角度,这样可以使用正常的角度依赖注入语法?

    注意
    问题是延迟加载独立模块。这个具体示例的一个简单解决方案是在ng-app.config期间使用缓存的$ providers创建“Pictures”对象,但这不是我想要的。我正在寻找适用于第三方模块的解决方案,例如angular-resource

3 个答案:

答案 0 :(得分:17)

我最终确定了我自己的名为angularAMD的实现,以下是使用它的示例站点:

http://marcoslin.github.io/angularAMD/

它处理配置功能和乱序模块定义。

希望这可以帮助其他人寻找帮助他们使用RequireJS和AngularJS集成的东西。

答案 1 :(得分:10)

在GitHub中查看我的项目:angular-require-lazy

该项目旨在展示一个想法并激励讨论。但是 你想要什么(检查expenses-view.js,它懒洋洋地加载ng-grid)。

我对评论,想法等很感兴趣。


(编辑)ng-grid Angular模块延迟加载如下:

    当激活expenses-view.js路由时,
  1. /expenses会被懒惰加载
  2. expenses-view.js将ng-grid指定为依赖项,因此RequireJs首先加载ng-grid
  3. ng-grid是调用angular.module(...)
  4. 的网格

    为了实现这一点,我用我自己的方法替换了(实际代理)真正的angular.module方法,它支持懒惰。请参阅bootstrap.jsroute-config.js(函数initLazyModules()callRunBlocks())。

    此实现有其缺点,您应该注意:

    1. 尚未实现配置功能。我不知道 lazily 是否可以提供 config-time 依赖项。
    2. 订单在定义中很重要。如果服务A依赖于B但A在模块中的B之后定义,则DI将失败。这是因为lazyAngular代理立即执行定义,不像真正的Angular,它确保在执行定义之前解析依赖关系。

答案 2 :(得分:1)

看起来Node.js模块ocLazyLoad定义了一种执行这种延迟加载的方法,虽然我不确定它与其他答案中的方法或硬盘相比它的性能如何 - 编码依赖项。任何关于此的信息将不胜感激。有趣的是,其他答案需要RequireJS才能运作,而ocLazyLoad则不需要。{/ p>

看起来ocLazyLoad定义了另一个在已经实例化包含模块之后注入依赖项的提供程序。它似乎通过基本上复制一些低级Angular行为来实现这一点,例如模块加载和提供,因此它看起来如此复杂。它似乎只是将每个核心Angular模块添加为依赖项:$compileProvider$q$injectorng等等。