我一直在使用 AngularJS 的种子应用程序,我注意到应用程序的大多数依赖项(控制器、指令、过滤器、服务)都是预先加载的。我想知道如何将 Angular 应用程序模块化为更小的字节,除非需要,否则不会加载依赖项。
例如,如果我有一个带有购物车的大型应用程序,添加/编辑送货地址、搜索结果、产品详细信息、产品列表等......购物网站上的用户可能永远不会遇到这些视图中的任何一个,但看起来就像(来自种子应用程序)这些所有视图的代码都是在启动时加载的。
AngularJS 中的模块化是如何减轻的?
我一直在使用 AngularJS 的种子应用程序,我注意到应用程序的大多数依赖项(控制器、指令、过滤器、服务)都是预先加载的。我想知道如何将 Angular 应用程序模块化为更小的字节,除非需要,否则不会加载依赖项。
例如,如果我有一个带有购物车的大型应用程序,添加/编辑送货地址、搜索结果、产品详细信息、产品列表等......购物网站上的用户可能永远不会遇到这些视图中的任何一个,但看起来就像(来自种子应用程序)这些所有视图的代码都是在启动时加载的。
AngularJS 中的模块化是如何减轻的?
这个关于模块化的问题在 SO 和 google 小组中经常被问到。我不是核心团队的一员,但我的理解如下:
您可以通过包含它们(ngInclude)或在指令/路由中引用它们来轻松地按需加载部分(HTML/模板片段)。所以至少你不需要预先下载所有的部分(虽然你可能想这样做,请参阅这里的另一个问题:有没有办法让 AngularJS 在开始时而不是在需要时加载部分?)
谈到 JavaScript(控制器、指令、过滤器等 - 基本上是在 AngularJs 模块中定义的所有内容),我相信截至今天,AngularJS 中不支持按需加载模块。核心团队关闭的这个问题就是一个证据:https ://github.com/angular/angular.js/issues/1382
缺少 AngularJS 模块的按需加载可能听起来像是一个很大的限制,但是:
现在,由于这个问题经常出现,我确信 AngularJS 团队已经意识到了这一点。事实上,我最近看到了一些实验性提交(https://github.com/mhevery/angular.js/commit/1d674d5bfc47d18dc4a14ee0feffe4d1f77ea23b#L0R396)表明支持可能正在进行中(或者至少有一些实验)。
我最近一直在玩 require 模块和 angular,并且我已经实现了部分和控制器的延迟加载。
无需对 Angular 源代码(版本 1.0.2)进行任何修改即可轻松完成。
存储库:https ://github.com/matys84pl/angularjs-requirejs-lazy-controllers 。
还有一个使用 Charles Fulnecky 制作的 yepnope ( https://github.com/cmelion/angular-yepnope ) 的实现。
我们需要的只是将此代码放入我们的应用程序配置中,如下所示:
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
]
并且所有组件在我们需要的地方都有“惰性”负载。