AngularJS懒加载不工作

AngularJS懒加载不工作

问题描述:

我有一个应用程序在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

所以最后我找到了解决办法:

我用决心,我的文档中添加脚本动态。所以,我的路线:

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

您是否已经一看,分为: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