2014-09-23 108 views
0

我有一個應用程序在angularjs每個控制器寫在不同的JS文件。AngularJS懶加載不工作

我只需要在routechange事件中調用這些文件。現在我成功地讓適當的控制器文件,但由於某種原因,其拋出的錯誤:

Error: [ng:areq] Argument 'ApplicantsController' is not a function, got undefined 
http://errors.angularjs.org/1.2.25/ng/areq?p0=ApplicantsController&p1=not%20a%20function%2C%20got%20undefined 
minErr/<@http://localhost/talentojo/app/js/angularjs/angular.js:78:5 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:1509:5 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:1520:76 
$ControllerProvider/this.$get</<@http://localhost/talentojo/app/js/angularjs/angular.js:7278:9 
nodeLinkFn/<@http://localhost/talentojo/app/js/angularjs/angular.js:6670:13 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:332:11 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6657:11 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6105:13 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6001:30 
z/<[email protected]://code.angularjs.org/1.2.25/angular-route.min.js:7:388 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6712:1 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6105:13 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6001:30 
createBoundTranscludeFn/[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6125:1 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:6732:11 
[email protected]://code.angularjs.org/1.2.25/angular-route.min.js:6:355 
$RootScopeProvider/this.$get</[email protected]://localhost/talentojo/app/js/angularjs/angular.js:12980:15 
l/<@https://code.angularjs.org/1.2.25/angular-route.min.js:11:127 
qFactory/defer/deferred.promise.then/[email protected]://localhost/talentojo/app/js/angularjs/angular.js:11572:15 
qFactory/defer/deferred.promise.then/[email protected]://localhost/talentojo/app/js/angularjs/angular.js:11572:15 
qFactory/ref/<.then/<@http://localhost/talentojo/app/js/angularjs/angular.js:11658:11 
$RootScopeProvider/this.$get</[email protected]://localhost/talentojo/app/js/angularjs/angular.js:12701:9 
$RootScopeProvider/this.$get</[email protected]://localhost/talentojo/app/js/angularjs/angular.js:12513:15 
$RootScopeProvider/this.$get</[email protected]://localhost/talentojo/app/js/angularjs/angular.js:12805:13 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:8378:34 
[email protected]://localhost/talentojo/app/js/angularjs/angular.js:8592:7 
createHttpBackend/</[email protected]://localhost/talentojo/app/js/angularjs/angular.js:8535:1 

我的代碼: HTML

<body> 

    <!-- Header Starts --> 
    <div ng-include="'assets/defaults/header.html'"></div> 
    <!-- Header Ends --> 
    <ul> 
     <li> 
      <a href="#">Home</a> 
     </li> 
     <li> 
      <a href="#applicants">Applicants</a> 
     </li> 
    </ul> 
    <div ng-view></div> 

    <!-- Footer Starts --> 
    <div ng-include="'assets/defaults/footer.html'"></div> 
    <!-- Footer Ends --> 
</body> 

路線:

var app = angular.module('TOJO',['ngRoute']); 

app.config(function($routeProvider, $locationProvider) { 
    $routeProvider.when('/', { 
     templateUrl : 'assets/home.html', 
     controller : 'HomeController' 
    }).when('/applicants', { 
     templateUrl : 'assets/applicants/list.html', 
     scriptUrl : 'assets/applicants/applicants.js' 
    }); 
}). 
run(function($rootScope, $location) { 
    $rootScope.$on("$routeChangeStart", function(event, next, current) { 
     if(next.scriptUrl !== undefined) 
      loadScript(next.scriptUrl); 
    }); 
}); 

app.controller('HomeController', function($scope) { 
    $scope.message = 'Look! I am home page.'; 
}); 

var loadScript = function(url, type, charset) { 
    if (type===undefined) type = 'text/javascript'; 
    if (url) { 
     var script = document.querySelector("script[src*='"+url+"']"); 
     if (!script) { 
      var heads = document.getElementsByTagName("head"); 
      if (heads && heads.length) { 
       var head = heads[0]; 
       if (head) { 
        script = document.createElement('script'); 
        script.setAttribute('src', url); 
        script.setAttribute('type', type); 
        if (charset) script.setAttribute('charset', charset); 
        head.appendChild(script); 
       } 
      } 
     } 
     return script; 
    } 
}; 

而文件applicants.js在路由變更時被呼叫:

app.controller('ApplicantsController',['$scope', function($scope) { 
    $scope.message = 'Look! I am home page.'; 
} 
]); 

list.html:

<div ng-controller="ApplicantsController">{{message}}</div> 
+0

我不認爲將角拿起新添加的腳本,一旦它運行 – thomaux 2014-09-23 06:48:58

+1

它的加載腳本,我檢查了螢火蟲,但我thk由於某種原因,它首先加載模板,然後js文件,因爲它拋出該錯誤 – 2014-09-23 06:49:56

+0

scriptUrl? WTF?這不是路由對象的公認屬性! https://docs.angularjs.org/api/ngRoute/provider/$routeProvider – Josep 2014-09-23 06:53:44

回答

1

所以最後我找到了解決辦法:

我用決心,我的文檔中添加腳本動態。所以,我的路線:

var app = angular.module('TOJO',['ngRoute']).service('HttpTojoService', Service); 
app.config(function($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) { 
    app.controllerProvider = $controllerProvider; 
    app.compileProvider = $compileProvider; 
    app.routeProvider  = $routeProvider; 
    app.filterProvider  = $filterProvider; 
    app.provide   = $provide; 

    $routeProvider.when('/', { 
     templateUrl : 'assets/home.html', 
     controller : 'HomeController' 
    }).when('/applicants', { 
     templateUrl : 'assets/applicants/list.html', 
     controller : 'ApplicantsController', 
     resolve:{deps:function($q, $rootScope){ 
      return routeResolver($q.defer(),['assets/applicants/applicants.js'],$rootScope); 
     }} 
    }).when('/jobs', { 
     templateUrl : 'assets/jobs/list.html', 
     controller : 'JobsController', 
     resolve:{deps:function($q, $rootScope){ 
      return routeResolver($q.defer(),['assets/jobs/jobs.js'],$rootScope); 
     }} 
    }); 
}); 

function routeResolver(deferred,dependencies,$rootScope){ 
    $script(dependencies, function() 
    { 
     $rootScope.$apply(function() 
     { 
      deferred.resolve(); 
     }); 
    }); 
    return deferred.promise; 
} 

和我的控制器:

app.controllerProvider.register('ApplicantsController',['$scope', 'HttpTojoService', function($scope, HttpTojoService) { 
    $scope.message = 'Look! I am applicants page.'; 
} 
]); 

,你也還需要scripts.js

2

您是否已經一看,分爲:https://docs.angularjs.org/api/ngRoute/provider/ $ routeProvider解決事件?

「如果這些依賴關係中有任何一個是承諾,路由器將等待它們全部被解析或在控制器實例化之前被拒絕。」 - >也許你可以將你的腳本插入到body/head標籤並返回一個承諾。

我使用它來包含樣式表例如

resolve: { 
       style: function() { 
        angular.element('head').append('<link href="*.css" rel="stylesheet">'); 
       } 
      } 
+0

解決方案我也需要使用緩存?因爲它會首先加載模板,然後是腳本文件,你覺得怎麼樣? – 2014-09-23 07:09:44

+0

如果你使用的是緩存,解析會等待,直到你的諾言被調用,也許還有模板渲染 - 我不知道說實話。 另一種方法是抓住location.startChange事件:https://docs.angularjs。org/api/ng/service/$ location 第三種方法是:$ compile,您可以編譯自己的模板,在開始編譯之前,您可以添加腳本標記。 我有一個與此有關的實際問題,但至少在這裏可以找到一個簡單的演示:http://plnkr.co/edit/7W9AbpaLqsYCecOWdIlz?p=preview 看看UIService和RouteProvider.js – graphefruit 2014-09-23 07:41:33

+0

我試過你的上面的代碼,但它的模板渲染後加載JS文件,因爲我得到相同的錯誤 – 2014-09-23 07:43:01