18

我一直在使用 AngularJS 的种子应用程序,我注意到应用程序的大多数依赖项(控制器、指令、过滤器、服务)都是预先加载的。我想知道如何将 Angular 应用程序模块化为更小的字节,除非需要,否则不会加载依赖项。

例如,如果我有一个带有购物车的大型应用程序,添加/编辑送货地址、搜索结果、产品详细信息、产品列表等......购物网站上的用户可能永远不会遇到这些视图中的任何一个,但看起来就像(来自种子应用程序)这些所有视图的代码都是在启动时加载的。

AngularJS 中的模块化是如何减轻的?

4

3 回答 3

21

这个关于模块化的问题在 SO 和 google 小组中经常被问到。我不是核心团队的一员,但我的理解如下:

  1. 您可以通过包含它们(ngInclude)或在指令/路由中引用它们来轻松地按需加载部分(HTML/模板片段)。所以至少你不需要预先下载所有的部分(虽然你可能想这样做,请参阅这里的另一个问题:有没有办法让 AngularJS 在开始时而不是在需要时加载部分?

  2. 谈到 JavaScript(控制器、指令、过滤器等 - 基本上是在 AngularJs 模块中定义的所有内容),我相信截至今天,AngularJS 中不支持按需加载模块。核心团队关闭的这个问题就是一个证据:https ://github.com/angular/angular.js/issues/1382

缺少 AngularJS 模块的按需加载可能听起来像是一个很大的限制,但是:

  • 说到性能,在衡量事情之前,我们无法确定;所以我建议简单地衡量这对你来说是否是一个真正的问题
  • 通常用 AngularJS 编写的代码非常小,我的意思是,非常小。这个小型代码库被压缩和压缩可能会导致一个非常小的工件下载

现在,由于这个问题经常出现,我确信 AngularJS 团队已经意识到了这一点。事实上,我最近看到了一些实验性提交(https://github.com/mhevery/angular.js/commit/1d674d5bfc47d18dc4a14ee0feffe4d1f77ea23b#L0R396)表明支持可能正在进行中(或者至少有一些实验)。

于 2012-09-28T19:40:13.237 回答
14

我最近一直在玩 require 模块和 angular,并且我已经实现了部分和控制器的延迟加载。

无需对 Angular 源代码(版本 1.0.2)进行任何修改即可轻松完成。

存储库:https ://github.com/matys84pl/angularjs-requirejs-lazy-controllers 。

还有一个使用 Charles Fulnecky 制作的 yepnope ( https://github.com/cmelion/angular-yepnope ) 的实现。

于 2012-11-21T18:57:06.633 回答
0

我们需要的只是将此代码放入我们的应用程序配置中,如下所示:

  application.config [
    "$provide", "$compileProvider", "$controllerProvider", "$routeProvider"
    , ($provide, $compileProvider, $controllerProvider, $routeProvider) ->

      application.controller = $controllerProvider.register
      application.provider = $provide.provider
      application.service = $provide.service
      application.factory = $provide.factory
      application.constant = $provide.constant
      application.value = $provide.value
      application.directive = -> $compileProvider.directive.apply application, arguments

      _when = $routeProvider.when

      $routeProvider.when = (path, route) ->
        loaded = off
        route.resolve = new Object unless route.resolve
        route.resolve[route.controller] = [
          "$q",
          ($q) ->

            return loaded if loaded

            defer = $q.defer()

            require [
              route.controllerUrl
            ], (requiredController) ->
              defer.resolve()
              loaded = on

            defer.promise
        ]

        _when.call $routeProvider, path, route

为了使用,在我们需要的模块中添加我们的组件(提供者、常量、指令等)。像那样:

define [
  "application"
  "services/someService"
], (
  application
) ->

  application.controller "chartController", [
    "$scope", "chart", "someService"
    , ($scope, chart, someService) ->

      $scope.title = chart.data.title

      $scope.message = chart.data.message

  ]

someService.coffee 文件:

define [
  "application"
], (
  application
) ->

  application.service "someService", ->

    @name = "Vlad"

并将我们的控制器路径添加到 controllerUrl 以进行路由:

  application.config [
    "$routeProvider"
    , ($routeProvider) ->

      $routeProvider

        .when "/table",
          templateUrl: "views/table.html"
          controller: "tableController"
          controllerUrl: "controllers/tableController"
          resolve:
            table: ($http) ->
              $http
                type: "GET"
                url: "app/data/table.json"
  ]

tableController.coffee 文件:

define [
  "application"
  "services/someService"
], (
  application
) ->

  application.controller "tableController", [
    "$scope", "table"
    , ($scope, table) ->

      $scope.title = table.data.title

      $scope.users = table.data.users

  ]

并且所有组件在我们需要的地方都有“惰性”负载。

于 2015-01-21T20:43:38.600 回答