AngularJS推迟返回直到完成

时间:2015-03-16 12:11:51

标签: angularjs

我尝试构建一项服务,在服务经过身份验证后返回 $ resource 。 我这样做了:

.factory('MoltinApi', ['$q', '$resource', '$http', 'moltin_options', 'moltin_auth', function ($q, $resource, $http, options, authData) {
    var api = $resource(options.url + options.version + '/:path', {
        path: '@path'
    });

    var authenticate = function () {
        if (!options.publicKey)
            return;

        var deferred = $q.defer();

        var request = {
            method: 'POST',
            url: options.url + 'oauth/access_token',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: "grant_type=implicit&client_id=" + options.publicKey
        };

        $http(request).success(function (response) {
            authData = response;

            deferred.resolve(api);
        });

        return deferred.promise;
    };

    return authenticate();
}])

但我无法在控制器中调用该资源:

.controller('HomeController', ['MoltinApi', function (moltin) {
    var self = this;

    moltin.get({ path: 'categories' }, function (categories) {
        console.log(categories);
    });
}]);

它只是声明'undefined不是一个函数'。 有人能告诉我我做错了吗?

更新1

因此,在使用建议的解决方案之后,这就是结果。

angular.module('moltin', ['ngCookies'])

// ---
// SERVICES.
// ---

.factory('MoltinApi', ['$cookies', '$q', '$resource', '$http', 'moltin_options', function ($cookies, $q, $resource, $http, options) {
    var api = $resource(options.url + options.version + '/:path', {
        path: '@path'
    });

    var authenticate = function () {
        if (!options.publicKey)
            return;

        var deferred = $q.defer();
        var authData = angular.fromJson($cookies.authData);

        if (!authData) {
            console.log('from api');
            var request = {
                method: 'POST',
                url: options.url + 'oauth/access_token',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                data: "grant_type=implicit&client_id=" + options.publicKey
            };

            deferred.resolve($http(request).success(function (response) {
                $cookies.authData = angular.toJson(response);
                setHeaders(response.access_token);
            }));
        } else {
            console.log('from cookie');
            deferred.resolve(setHeaders(authData.access_token));
        }

        return deferred.promise;
    };

    var setHeaders = function (token) {
        $http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
    }

    return authenticate().then(function (response) {
        return api;
    });
}]);

并称之为我必须这样做:

.controller('HomeController', ['MoltinApi', function (moltin) {
    var self = this;

    moltin.then(function (api) {
        api.get({ path: 'categories' }, function (categories) {
            console.log(categories);
            self.sports = categories.result;
        });
    });
}]);

但我想做的是:

.controller('HomeController', ['MoltinApi', function (moltin) {
    var self = this;

    moltin.get({ path: 'categories' }, function (categories) {
        console.log(categories);
    }, function (error) {
        console.log(error);
    });
}]);

如您所见,该服务正在检查我们是否在返回API之前已经过身份验证。一旦经过身份验证,就会返回API,然后用户可以调用api而无需再次进行身份验证。 有人可以帮我重构这项服务,所以我可以在不必 moltin.then()的情况下调用它吗?

1 个答案:

答案 0 :(得分:0)

您将在MoltinApi工厂中返回authenticate函数调用,因此您将返回promise。并且方法get在promise

中不存在