我在一个拥有数十个模板的应用中使用ui-router
。每个模板都有一个控制器。
从我一直在阅读的内容来看,这样的事情(设置路线)应该有效:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('start', {
url: '/start',
templateUrl: 'partials/start.html',
controller: 'StartCtrl'
})
});
这是假设之前定义的StartCtrl。该应用程序最终将拥有数十个控制器,并且不希望一次性下载所有控制器的开销。如何仅在请求模板时加载控制器?
答案 0 :(得分:4)
我为此使用RequireJS。还有一个提供者,比如lazyProvider:
在懒惰的提供者中......
this.resolve = function(controller){
return { myCtrl: ['$q',function ($q){
var defer = $q.defer();
require(['/app/controllers/'+controller,'myApp'],function(ctrl,myApp){
myApp.register.controller(controller,ctrl);
defer.resolve();
}
return defer.promise;
}]
};
};
在您的ui-router resolve:
属性中执行:
resolve: lazyProvider.resolve('myCtrl');
您需要在应用上公开提供商注册表,以便稍后注册,例如:
myApp.config(function($urlRouterProvider, $stateProvider,
$controllerProvider, $compileProvider, $filterProvider,$provide){
//If your myApp isn't already a module...
define('myApp',[],function(){return myApp});
myApp.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service,
constant: $provide.constant
}
你的控制员:
define(['/dependencies'],function(deps){
function MyCtrl($scope){...}
return MyCtrl;
}
这实际上是Dan Wahlin分享的here
答案 1 :(得分:1)
在使用@calebboyd示例后,我使用System.js和ES6进行了工作。我喜欢这个实现的是,使用ES6模块,一切都只取决于已经唯一的文件名,因此您不需要关心控制器名称冲突甚至命名它们。控制器是匿名的。
此实现假设您有一个文件夹“pages”,其中包含模板/控制器对,如下所示:
/pages /page1.html /page1.js /page2.html /page2.js
访问/#pages/page1
后,它将动态加载模板和控制器。
这是你的“app.js”:
import angular from 'angular';
import 'angular-ui-router';
angular.module('app', ['ui.router'])
.config(($stateProvider, $urlRouterProvider, $controllerProvider) => {
// save reference to the register method, so we can use inside the 'resolve'
var registerController = $controllerProvider.register;
// register a single state that takes the page name as a parameter
$stateProvider
.state('pages', {
url: "/pages/:name",
// the url and the controller name are dynamically created
templateUrl: $stateParams => "pages/" + $stateParams.name + ".html",
controllerProvider: $stateParams => $stateParams.name + '_DynamicController as vm',
resolve: {
'ctrl': ($stateParams, $q) => {
var script = 'pages/' + $stateParams.name;
var controllerName = $stateParams.name + '_DynamicController';
// once System.js loads the module, we register using the
// saved registerController function with the dynamic name
return System.import(script)
.then(ctrl => registerController(controllerName, ctrl['default']));
}
}
});
});
以下是“page1.js”中的示例控制器:
export default class {
constructor() {
this.data = "inside the controller";
}
}
“page1.html”中的示例模板:
<h1>Page1 Template</h1>
Loaded: {{ vm.data }}