如何使用AngularJS和RequireJS从外部文件注入服务?

时间:2014-10-18 22:46:37

标签: javascript angularjs dependency-injection requirejs

我从外部文件注入控制器,我想从外部文件为服务做同样的事情。它应该在工厂声明中注册。

注入控制器

控制器

'use strict';

define(['angular', 'services'], function (angular) {
    return angular.module('vcApp.controllers', ['vcApp.services'])
        .controller('AuthCtrl', ['$scope', '$injector','AuthService', function($scope, $injector, AuthService) {
            require(['auth/authCtrl'], function(authCtrl) {
                $injector.invoke(authCtrl, this, {'$scope': $scope, 'AuthService':AuthService});
            });
        }]);
});

authCtrl

define([], function() {
    return ['$scope', '$routeParams', '$location', '$http', 'AuthService', function($scope, $routeParams, $location, $http, authService) {

        $scope.signIn = function() {
        ...
        }

        $scope.$apply();
    }];
});

现在我想注入服务

服务

'use strict';

define(['angular'], function (angular) {
    angular.module('vcApp.services', [])
    .factory('AuthService', ['$http', '$injector', function($http, $injector) {
        require(['auth/authService'], function(authService) {
            $injector.invoke(authService, this, {'$http': $http});
        });
    }]);
});

authService

define([], function() {
    return ['$http', function ($http) {
        return {
            login: login
        };

        function login(username, password) {
            var request = $http(...);
            return(request);
        }
    }]
});

当authController调用authService.login(...)时,它会抛出错误Error: [$injector:undef] Provider 'AuthService' must return a value from $get factory method.

此代码的灵感来自angular-requirejs-seed项目。

1 个答案:

答案 0 :(得分:2)

正如它所说,Angular的factory()应该返回服务对象。你可能会遇到类似的事情:

define(['angular'], function (angular) {
    angular.module('vcApp.services', [])
    .factory('AuthService', ['$http', '$injector', function($http, $injector) {
        var stub = {};
        require(['auth/authService'], function(authService) {
            angular.extend(stub, $injector.invoke(authService, this, {'$http': $http}));
        });
        return stub;
    }]);
});

在这里,您可以为服务定义存根,并在服务实际延迟加载时对其进行扩展。

(顺便说一下,我认为$injector.invoke()的最后两个参数在这种情况下是多余的。)

如果你想要另外一个关于混合RequireJS和Angular的想法,那么它与延迟加载和r.js优化器配合得很好,你可以看一下angular-require-lazy