Angular JS延迟加载不起作用

时间:2014-09-23 06:46:56

标签: angularjs lazy-loading

我在angularjs中有一个应用程序,其中每个控制器都是用不同的JS文件编写的。

我只需要在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
assertArg@http://localhost/talentojo/app/js/angularjs/angular.js:1509:5
assertArgFn@http://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
forEach@http://localhost/talentojo/app/js/angularjs/angular.js:332:11
nodeLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6657:11
compositeLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6105:13
publicLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6001:30
z/<.link@https://code.angularjs.org/1.2.25/angular-route.min.js:7:388
nodeLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6712:1
compositeLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6105:13
publicLinkFn@http://localhost/talentojo/app/js/angularjs/angular.js:6001:30
createBoundTranscludeFn/boundTranscludeFn@http://localhost/talentojo/app/js/angularjs/angular.js:6125:1
controllersBoundTransclude@http://localhost/talentojo/app/js/angularjs/angular.js:6732:11
v@https://code.angularjs.org/1.2.25/angular-route.min.js:6:355
$RootScopeProvider/this.$get</Scope.prototype.$broadcast@http://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/wrappedCallback@http://localhost/talentojo/app/js/angularjs/angular.js:11572:15
qFactory/defer/deferred.promise.then/wrappedCallback@http://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</Scope.prototype.$eval@http://localhost/talentojo/app/js/angularjs/angular.js:12701:9
$RootScopeProvider/this.$get</Scope.prototype.$digest@http://localhost/talentojo/app/js/angularjs/angular.js:12513:15
$RootScopeProvider/this.$get</Scope.prototype.$apply@http://localhost/talentojo/app/js/angularjs/angular.js:12805:13
done@http://localhost/talentojo/app/js/angularjs/angular.js:8378:34
completeRequest@http://localhost/talentojo/app/js/angularjs/angular.js:8592:7
createHttpBackend/</xhr.onreadystatechange@http://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>

2 个答案:

答案 0 :(得分:2)

你已经看过了,进入:https://docs.angularjs.org/api/ngRoute/provider/ $ routeProvider解决事件?

“如果这些依赖项中的任何一个是promise,路由器将等待它们全部解析,或者在实例化控制器之前拒绝一个。” - &GT;也许你可以将你的脚本插入到body / head标签中并返回一个promise。

我用它来包括样式表,例如

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

答案 1 :(得分:1)

所以最后我找到了解决方案:

我使用了resolve,动态地在我的文档中添加脚本。所以我的路线:

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