问题描述
你能帮助我了解如何在示例中的视图之前加载下面控制器?它看起来像的观点只是立即加载同时控制器还没有加载。
// app.js
$ stateProvider.state('指数',{
网址:/,
观点:{
顶部菜单:{
templateUrl:/首页/顶部菜单
控制器:函数($范围,$喷油器){
需要(['控制器/顶菜单控制器'],功能(模块){
$ injector.invoke(模块,为此,{'$范围:$范围});
});
}
}
}
});//top-menu-controller.js
定义(['应用'],功能(应用程序){
app.controller('TopMenuCtrl',['$范围',函数($范围){
$ scope.message =它的工作原理;
}]);
});//主页/顶部菜单
< H3>顶部菜单和LT; / H3 GT&;
< DIV NG控制器=TopMenuCtrl>
{{信息}}
< / DIV>
在这里。
让我们这样的 index.html的的:
<!DOCTYPE HTML>
< HTML和GT;
< HEAD>
<标题>我懒< /标题>
< /头> <机身NG-应用=应用程序> < A HREF =#/家>#/家< / A> //我们有三种状态 - 家更是不可以偷懒
&所述; A HREF =#/>#/&下; / A> - 指数//索引很懒,有两种观点
< A HREF =#/其他>#/其它< / A> //'其他'是懒惰的未命名视图 < DIV数据的用户界面视图=顶部菜单>< / DIV>
< DIV数据的用户界面视图=>< / DIV> &所述; SCRIPT SRC =angular.js>&下; /脚本> //标准角
<脚本SRC =角-UI-router.js>< / SCRIPT> //和UI路由器scritps &所述; SCRIPT SRC =的script.js>&下; /脚本> //我们的应用程序 <脚本数据主要=main.js//懒惰依赖
SRC =require.js>&下; /脚本> < /身体GT;
< / HTML>
让我们来观察 main.js
- 在RequireJS配置:
require.config({ //的baseUrl:JS /脚本
的baseUrl:, //别名库的路径
路径:{ //这里我们定义路径名字
//使控制器和他们的懒惰的文件名独立 TopMenuCtrl:Controller_TopMenu,
ContentCtrl:Controller_Content,
OtherCtrl:Controller_Other,
}, DEPS:['应用']
});
事实上,我们只为我们的 ControllerNames
别名(路径) - 和他们的 Controller_Scripts.js
文件。而已。的此外,我们返回到需要的应用程序,但是我们将在以后的情况下使用不同的功能 - 注册延迟加载控制器的
什么是的 DEPS:['应用']
是什么意思?首先,我们需要提供文件的 app.js (以下简称程序是指找到 app.js
)的
定义([],函数(){ VAR应用= angular.module(应用);
返回程序;
})
这返回的值是一个我们可以要求在每一个异步加载的文件
定义(['应用'],功能(应用程序){
//这里我们将有机会获得该模块(应用程序)
});
我们将如何负载控制器懒洋洋地?这里已经被证明为 ngRoute
We will ask angular for a reference to $controllerProvider
- and use it later, to register controllers.
This is the first part of our script.js:
// I. the application
var app = angular.module('app', [
"ui.router"
]);
// II. cached $controllerProvider
var app_cached_providers = {};
app.config(['$controllerProvider',
function(controllerProvider) {
app_cached_providers.$controllerProvider = controllerProvider;
}
]);
As we can see, we just created the application 'app' and also, created holder app_cached_providers
(following the angularAMD style). In the config phase, we ask angular for $controllerProvider
and keep reference for it.
Now let's continue in script.js:
// III. inline dependency expression
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;
}],
},
});
}
]);
This part above shows two states declaration. One of them - 'home'
is standard none lazy one. It's controller is implicit, but standard could be used.
The second is state named "other"
which does target unnamed view ui-view=""
. And here we can firstly see, the lazy load. Inside of the resolve (see:)
Resolve
With that in our suite, we know, that the controller (by its name) will be searched in angular repository once the resolve is finished:
// this controller name will be searched - only once the resolve is finished
controller: "OtherCtrl",
// let's ask RequireJS
resolve: {
loadOtherCtrl: ["$q", function($q) {
// wee need $q to wait
var deferred = $q.defer();
// and make it resolved once require will load the file
require(["OtherCtrl"], function() { deferred.resolve(); });
return deferred.promise;
}],
},
Good, now, as mentioned above, the main contains this alias def
// alias libraries paths
paths: {
...
"OtherCtrl" : "Controller_Other",
And that means, that the file "Controller_Other.js" will be searched and loaded. This is its content which does the magic. The most important here is use of previously cached reference to $controllerProvider
// content of the "Controller_Other.js"
define(['app'], function (app) {
// the Default Controller
// is added into the 'app' module
// lazily, and only once
app_cached_providers
.$controllerProvider
.register('OtherCtrl', function ($scope) {
$scope.message = "OtherCtrl";
});
});
the trick is not to use app.controller()
but
$controllerProvider.Register
Finally there is another state definition, with more narrowed resolve... a try to make it more readable:
// IV ... build the object with helper functions
// then assign to state provider
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);
}]);
Above we can see, that we resolve two controllers for both/all named views of that state
That's it. Each controller defined here
paths: {
"TopMenuCtrl": "Controller_TopMenu",
"ContentCtrl": "Controller_Content",
"OtherCtrl" : "Controller_Other",
...
},
will be loaded via resolve and $controllerProvider
- via RequireJS - lazily. Check that all here
Similar Q & A: AngularAMD + ui-router + dynamic controller name?
这篇关于角UI的路由器requirejs,控制器的延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!