registra o controlador lazyloaded angularjs

9

Eu quero carregar controladores assim:

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

O controlador carrega, mas eu recebo o seguinte erro, levando-me a acreditar que o controlador não foi registrado:

Argument 'SearchCtrl' is not aNaNunction, got undefined

Então, minha pergunta é: como eu faria para registrar o controlador ao carregá-lo preguiçosamente, como mostrado?

O controlador

é definido como:

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

});

Há algo que eu possa fazer para forçar o registro do controlador?

EDITAR O APLICATIVO JÁ ESTÁ CONSTRUÍDO E TUDO FUNCIONA MUITO. ESTA PERGUNTA PERTA A APENAS A CARGA DE CARGA.

O problema é exatamente como definido, o controlador não está registrado porque o processo de bootstrapping já foi executado. Eu estou procurando alguma maneira de registrar o controlador quando é lazyloaded.

minha função loader ( $util.load() se parece com isso:

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

},
    
por r3wt 22.02.2017 в 18:24
fonte

1 resposta

2

Eu mesmo consegui resolver isso substituindo angular.module() por uma função personalizada e, dentro dessa função personalizada, eu transfiro as chamadas para appInstance.controller para $ controllerProvider.register (). está funcionando, eu não tenho certeza de como isso é bom, mas eu não me importo, desde que não quebre nada.

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)

Isso funciona muito bem, mas apenas para os controladores. A seguir, um exemplo completo abrangendo controladores, diretivas, componentes, fábricas, serviços, valores, constantes e filtros:

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

}]);
    
por r3wt 28.02.2017 / 00:58
fonte