I在这里
创建了一个工作的plunker。
让我们有这个
index.html:
<!DOCTYPE html>
<html>
<head>
<title>my lazy</title>
</head>
<body ng-app="app">
<a href="#/home">#/home</a> // we have three states - 'home' is NOT lazy
<a href="#/">#/</a> - index // 'index' is lazy, with two views
<a href="#/other">#/other</a> // 'other' is lazy with unnamed view
<div data-ui-view="topMenu"></div>
<div data-ui-view=""></div>
<script src="angular.js"></script> // standard angular
<script src="angular-ui-router.js"></script> // and ui-router scritps
<script src="script.js"></script> // our application
<script data-main="main.js" // lazy dependencies
src="require.js"></script>
</body>
</html>
让我们观察
main.js
- RequireJS 的配置:
require.config({
baseUrl: "",
paths: {
"TopMenuCtrl": "Controller_TopMenu",
"ContentCtrl": "Controller_Content",
"OtherCtrl" : "Controller_Other",
},
deps: ['app']
});
实际上,我们只为我们的
ControllerNames
和它们的
Controller_Scripts.js
文件创建别名(路径)。就是这样。
此外,我们返回需要应用程序,但在我们的情况下,我们稍后将使用不同的功能 - 注册惰性加载的控制器。
deps: ['app']
的意思是什么?首先,我们需要提供文件
app.js ('app'表示查找app.js
):
define([], function() {
var app = angular.module('app');
return app;
})
这个返回值是我们可以在每个异步加载的文件中请求的。
define(['app'], function (app) {
});
我们如何实现控制器的懒加载?就像这里已经证明的那样,对于
ngRoute
。
angularAMD是一种实用工具,支持在AngularJS应用程序中使用RequireJS,并支持按需加载第三方模块,例如angular-ui。
我们将向Angular请求引用$controllerProvider
- 稍后将使用它来注册控制器。
这是我们script.js的第一部分:
var app = angular.module('app', [
"ui.router"
]);
var app_cached_providers = {};
app.config(['$controllerProvider',
function(controllerProvider) {
app_cached_providers.$controllerProvider = controllerProvider;
}
]);
我们可以看到,我们刚刚创建了名为 'app' 的应用程序,并且还创建了 holder
app_cached_providers
(遵循 angularAMD 风格)。在配置阶段,我们请求 angular 获取
$controllerProvider
并保留对它的引用。
现在让我们继续在
script.js 中:
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise("/home");
$stateProvider
.state("home", {
url: "/home",
template: "<div>this is home - not lazily loaded</div>"
});
$stateProvider
.state("other", {
url: "/other",
template: "<div>The message from ctrl: {{message}}</div>",
controller: "OtherCtrl",
resolve: {
loadOtherCtrl: ["$q", function($q) {
var deferred = $q.defer();
require(["OtherCtrl"], function() { deferred.resolve(); });
return deferred.promise;
}],
},
});
}
]);
这部分展示了两种状态声明。其中之一是标准的非懒加载状态
'home'
。它的控制器是隐式的,但可以使用标准方式。
第二个状态名为
"other"
,它指向未命名的视图
ui-view=""
。在这里,我们首先可以看到懒加载。在
resolve内部
(参见:)
您可以使用resolve为状态提供自定义内容或数据。resolve是一个可选的依赖项映射,应该注入到控制器中。
如果这些依赖关系中有任何承诺,它们将在控制器实例化之前被解决并转换为值,并且$stateChangeSuccess事件将被触发。
有了这个,我们知道,控制器(根据其名称)将在解析完成后在Angular存储库中搜索:
controller: "OtherCtrl",
resolve: {
loadOtherCtrl: ["$q", function($q) {
var deferred = $q.defer();
require(["OtherCtrl"], function() { deferred.resolve(); });
return deferred.promise;
}],
},
好的,现在正如上面提到的那样,主要内容包含了这个别名def
// alias libraries paths
paths: {
...
"OtherCtrl" : "Controller_Other",
这意味着将搜索并加载文件“Controller_Other.js”。以下是它的内容,它实现了
魔法。最重要的是先前缓存的
$controllerProvider
引用的使用。
define(['app'], function (app) {
app_cached_providers
.$controllerProvider
.register('OtherCtrl', function ($scope) {
$scope.message = "OtherCtrl";
});
});
"关键是不要使用
app.controller()
,而是"
$controller服务用于Angular创建新的控制器。该提供程序允许通过register()
方法进行控制器注册。
最后还有另一个状态定义,具有更加精细的解析... 试图使其更易读:
var loadController = function(controllerName) {
return ["$q", function($q) {
var deferred = $q.defer();
require([controllerName], function() {deferred.resolve(); });
return deferred.promise;
}];
}
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
var index = {
url: "/",
views: {
"topMenu": {
template: "<div>The message from ctrl: {{message}}</div>",
controller: "TopMenuCtrl",
},
"": {
template: "<div>The message from ctrl: {{message}}</div>",
controller: "ContentCtrl",
},
},
resolve : { },
};
index.resolve.loadTopMenuCtrl = loadController("TopMenuCtrl");
index.resolve.loadContentCtrl = loadController("ContentCtrl");
$stateProvider
.state("index", index);
}]);
以上我们可以看到,我们解决了该状态下两个/所有命名视图的两个控制器。
就是这样。在这里定义了每个控制器。
paths: {
"TopMenuCtrl": "Controller_TopMenu",
"ContentCtrl": "Controller_Content",
"OtherCtrl" : "Controller_Other",
...
},
将通过resolve异步加载,$controllerProvider
将通过RequireJS进行懒加载。请检查所有这里。
类似的问题和回答:AngularAMD + ui-router + 动态控制器名称?