我想像这样加载控制器:
.state({
name: 'app.search',
url: 'search?q&opts',
templateUrl: '/templates/search.html',
controller: 'SearchCtrl',
resolve: {
deps: function($util){
return $util.load(['/ctrl/SearchCtrl.js']);
}
}
})
控制器加载但我收到以下错误,导致我认为控制器未注册:
Argument 'SearchCtrl' is not aNaNunction, got undefined
所以我的问题是,如图所示懒惰加载时如何注册控制器。
控制器定义为:
app.module('app').controller('SearchCtrl',function(){
});
我有什么办法可以强制控制器注册吗?
编辑应用程序已经完成并且所有工作都很精细。本问题只适用于LAZYLOADING。
问题与定义完全一样,控制器未注册,因为引导过程已经运行。我正在寻找一些在延迟加载时注册控制器的方法。
我的加载器功能($util.load()
看起来像这样:
load: function (){
if(arguments.length > 1){
var items = arguments;
}else{
var items = arguments[0];
}
var _self = this;
return $q(function(resolve,reject){
if(items.length == 0){
return resolve();
}
_self.async( items, function(item,next){
if(item.indexOf('.js') != -1){
_self.loadOne('script',item,next,function(err){
next(err);
});
}
else if(item.indexOf('.css') != -1){
_self.loadOne('link',item,next);
}else{
next();
}
},function(errors,results){
$timeout(function() {
$rootScope.$apply();// @Claies suggestion
if(errors){
reject(errors);
}else{
resolve();
}
});
});
});
},
答案 0 :(得分:2)
我能够通过使用自定义函数覆盖angular.module()
来自行解决,并且在此自定义函数中,我将对appInstance.controller的调用传递给$ controllerProvider.register()。它是有效的,我不确定它是多么合适,但只要它不会破坏任何东西我就不在乎。
var mod = angular.module('myModule',[]); //define my module
mod.config(['$controllerProvider',function($controllerProvider){
mod._cRegister = $controllerProvider;//store controllerProvider onto the app instance.
var mFunc = angular.module; // copy actual module function from angular
//override angular.module with custom function
angular.module = function(){
var app = mFunc.apply(this,arguments);// proxy to the real angular.module function to get an app instance
var cFunc = app.controller;//copy actual controller function from app instance
app.controller = function(){
mod._cRegister.register.apply(this,arguments); // try register on the controllerProvider instance as well
return this;//return app instance so user can chain calls or whatever.
}.bind(app);
return app;//return app instance, just as angular does.
}.bind(angular);
}]);
//rest of module code (including the loader)
这很好用,但仅适用于控制器。以下是一个完整的示例,涵盖控制器,指令,组件,工厂,服务,值,常量和过滤器:
var mod = angular.module('myModule',[]);
mod.config(['$controllerProvider','$compileProvider','$filterProvider','$provide',function($controllerProvider,$compileProvider,$filterProvider,$provide){
mod.$controllerProvider = $controllerProvider;
mod.$compileProvider = $compileProvider;
mod.$filterProvider = $filterProvider;
mod.$provide = $provide;
var map = {
controller: ['$controllerProvider','register'],
filter: ['$filterProvider','register'],
service: ['$provide','service'],
factory: ['$provide','factory'],
value: ['$provide','value'],
constant: ['$provide','constant'],
directive: ['$compileProvider','directive'],
component: ['$compileProvider','component']
};
var bootStrapped = [];
var mFunc = angular.module;
angular.module = function(){
var app = mFunc.apply(this,arguments);
//only override properties once.
if(bootStrapped.indexOf(arguments[0]) == -1){
for(var type in map){
var c = mod;
var d = map[type];
for(var i=0;i<d.length;i++){
c = c[d[i]];// recurse until reaching the function
}
//now inject the function into an IIFE so we ensure its scoped properly
!function(app,type,c){
app[type] = function(){
c.apply(this,arguments);
return this;//return the app instance for chaining.
}.bind(app);
}(app,type,c);
}
bootStrapped.push(arguments[0]);//mark this instance as properly monkey patched
}
return app;
}.bind(angular);
}]);