2017-02-22 5 views
9

난과 같이 컨트롤러를로드 할 AngularJS와 :레지스터 lazyloaded 컨트롤러는

.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에만 적용됩니다.

문제는 정확히 정의 된 바와 같이 부트 스트랩 프로세스가 이미 실행 되었기 때문에 컨트롤러가 등록되지 않았습니다. lazyloaded 때 컨트롤러를 등록 할 수있는 몇 가지 방법을 찾고 있어요. 나는 사용자 정의 기능을 angular.module()를 재정 의하여 그것을 자신을 해결할 수 있었다

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

로더가 컨트롤러 파일을로드하고 실행하지만 * resolve *가 반환되기 전에 * $ rootScope. $ apply()'*를 사용해야한다. oc-lazyLoad와 같이이 태스크를 위해 설계된 모듈을 사용할 수도 있습니다. https://oclazyload.readme.io/docs/with-your-router – Claies

답변

2

,이 사용자 정의 함수 내에서 내가 $ controllerProvider에 appInstance.controller에 대한 호출을 전달합니다과 같이

내 로더 기능 ($util.load() 보인다 .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) 

이 있지만 컨트롤러, 좋은 작품 다음은 전체 예제 코드입니다. 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

@ lazyloading을위한 작은 라이브러리가 필요한지 설명하십시오. github/bower 체크 아웃'ng-util' 패키지에 하나 있습니다. 그 중 하나는 lazyloading뿐만 아니라 반환 명령이 보장되는 동기 및 비동기 반복기 (함수 대기열)와 임의의 지시문 및 필터와 같은 모든 유형의 똥을 수행합니다. 모두 대략 2.8kb에서 – r3wt

+0

그것을 듣기 좋게, 나는 저것 같이 무언가를 한동안 찾고 있었다. 다른 유용한 패키지가 있으면 주저하지 마세요. – Disfigure