在解决之前等待装载工厂

时间:2015-02-27 16:55:15

标签: javascript angularjs angularjs-routing

我有这样的代码:

meow.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider
    .when('/page', {
        templateUrl: 'application/partials/page.html',
        controller: 'index',
        resolve: {'page': ['$resolve', function($resolve) {return $resolve.page();}]}
    })
    .when('/page2', {
        templateUrl: 'application/partials/page2.html',
        controller: 'index',
        resolve: {'page2': ['$resolve', function($resolve) {return $resolve.page2();}]}
    })
    ...
    .otherwise({
        redirectTo: '/error'
    });
}]);
meow.factory('$resolve', ['$q', '$user', function($q, $user) {
    return {
        page: function() {
            var deferred = $q.defer();

            if ($user.logged()) {
                $http.get('/json/page')
                .success(function(data, status, headers, config) {
                    deferred.resolve();
                })
                .error(function(data, status, headers, config) {
                    deferred.reject();
                });
            } else {
                deferred.reject();
            }

            return deferred.promise;
        }
        page2:...
        page3:...
        ...
    }
}]);

正如您所看到的那样$resolve工厂检查用户访问权限:$user.logged(),但$user是异步的,首次加载时会导致访问问题。

问题是如何让我所有的决心等待$user? 我有$ user.q()函数,它提供了承诺,但是如何将它注入我的代码中进行所有解析?或者可能是其他一些包含$routeChangeStart$locationChangeStart事件的解决方案?或者我应该在每个决心中插入$user.q().then(...)吗?

更新1:
我的用户代码:

meow.factory('$user', ['$q', '$http', function($q, $http) {
    var id = null;
    var accesslevel = 0;

    function update() {
        var deferred = $q.defer();

        $http.get('/json/user')
        .success(function(data, status, headers, config) {
            if (data.logged) {
                id = data.id;
                accesslevel = data.accesslevel;
            } else {
                id = null;
                accesslevel = 0;
            }
            deferred.resolve();
        })
        .error(function(data, status, headers, config) {
            deferred.reject();
        });

        return deferred.promise;
    }

    var q = update();

    return {
        logged: function() { return (id) ? true : false; },
        id: function() { return id; },
        accesslevel: function() { return accesslevel; },
        reset: function() {
            id = null;
            accesslevel = 0;
        },
        update: function() { return q = update(); },

        q: function() { return q; }
    };
}]);

不是控制器应该等待$user.q(),解决应该。当我尝试将其作为$routeProvider中的附加解决方案时,page决定尝试加载/json/page,但不应该在$user.q()解决并$user.logged() = true之前。

所以唯一的方法是添加

    page: function() {
        var deferred = $q.defer();

        $user.q().then(function() {
            if ($user.logged()) {
                $http.get('/json/page')
                .success(function(data, status, headers, config) {
                    deferred.resolve();
                })
                .error(function(data, status, headers, config) {
                    deferred.reject();
                });
            } else {
                deferred.reject();
            }
        });

        return deferred.promise;
    }

每个决心?

2 个答案:

答案 0 :(得分:2)

您通常会像这样处理依赖关系的方式是让user自己解决,然后让其他解决依赖于它,如下所示:

resolve: {
  user: function($user) {
    return $user.q();
  },
  somethingElse: function(user, $otherService) {
    // Whatever else
  }
}

这是<{3}}中涵盖的

答案 1 :(得分:0)

$ user本身可以是解析所有服务方法的承诺,也可以单独解析每个服务。

用法

$user.then(function(userService) {
    userService.logged();
});

分辨率

var userDeferred= $q.defer();
userDeferred.resolve({
    logged: function() {
        return false;
    }
});
return userDeferred.promise;