注册lazyloaded controller angularjs

r3w*_*3wt 9 lazy-loading angularjs lazyload

我想像这样加载控制器:

.state({
    name: 'app.search',
    url: 'search?q&opts',
    templateUrl: '/templates/search.html',
    controller: 'SearchCtrl',
    resolve: {
        deps: function($util){
            return $util.load(['/ctrl/SearchCtrl.js']);
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

控制器加载,但我得到以下错误,让我相信控制器没有注册:

Argument 'SearchCtrl' is not aNaNunction, got undefined

所以我的问题是,如果如图所示懒惰地加载控制器,我将如何注册控制器.

控制器定义为:

app.module('app').controller('SearchCtrl',function(){

});
Run Code Online (Sandbox Code Playgroud)

有什么办法可以强制控制器注册吗?

编辑应用程序已经建立并且所有工作都很精细.这个问题只适用于拉兹加勒丁.

问题与定义完全一样,控制器未注册,因为引导过程已经运行.我正在寻找一些在延迟加载时注册控制器的方法.

我的加载器功能($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();
                }
            });
        });
    });

},
Run Code Online (Sandbox Code Playgroud)

r3w*_*3wt 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)
Run Code Online (Sandbox Code Playgroud)

这非常有效,但仅适用于控制器。以下是一个完整的示例,涵盖控制器、指令、组件、工厂、服务、值、常量和过滤器:

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);    

}]);
Run Code Online (Sandbox Code Playgroud)