2017-02-22 84 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