2017-02-22 53 views
9

我想负载控制器,像这样:寄存器lazyloaded控制器angularjs

.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(){ 

}); 

有什么我可以做,以迫使控制器注册?

编辑该应用程序已建成,所有作品都是精美的。这个问题只适用于懒惰。

问题与定义完全一样,控制器未注册,因为引导进程已经运行。我正在寻找一些方法来注册控制器,当它被延迟加载。

我的装载函数($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

您是否有单独声明的模块? – Sajeetharan

+0

应用模块?当然。这个应用程序已经建成,但所有的代码都在一个单一的文件。我试图将所有代码拆分为单独的文件和延迟加载 – r3wt

+1

,在加载器加载并执行控制器文件之前,您需要使用'$ rootScope。$ apply()'*,然后才能返回解析。您也可以使用专为此任务设计的模块,如oc-lazyLoad。 https://oclazyload.readme.io/docs/with-your-router – Claies

回答

2

我可以用自定义函数重载angular.module()解决它自己,这个自定义函数中我通过到$ controllerProvider调用appInstance.controller .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) 

这个伟大的工程,但仅限于控制器。以下是一个完整的示例coverin g控制器,指令,组件,工厂,服务,数值,常量和过滤器:

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

}]); 
+1

疯狂的家伙:快乐:干得好!我会试试 – Disfigure

+0

@Disfigure如果您需要一个小型库来进行延迟加载,我已经在github/bower checkout'ng-util'软件包中加入了一个。它不仅延迟加载,它还执行所有类型的shit,如同步和异步迭代器(函数队列),保证返回顺序,以及一些随机指令和过滤器。全部在大约2.8kb – r3wt

+0

很高兴听到,我一直在寻找这样的事情。如果你有任何其他有用的包,不要犹豫,哈哈 – Disfigure