在Angular UI路由器中访问多个promises数据

时间:2015-01-28 16:12:26

标签: javascript angularjs angular-ui-router

我正在尝试使用$q服务来解决使用AngularUI路由器的$q.all()函数的多个承诺,但由于某些原因,这会失败或者无法按预期工作。

这是我的配置文件的一部分,其中包含$stateProvider

.state('home.team',
{
    url : '^/team',
    views : {
        'main' : {
            templateUrl : ConfigProvider.path.views + '/segment/home/team.html',
            controller : 'SegmentHomeTeamCtrl',
            resolve : {
                promiseData : function(ResolveService) { return ResolveService.resolveHomeTeam(); }
            }
        },
        'subMenu' : {
            templateUrl : ConfigProvider.path.views + '/menu/home/team.html'
        }
    }
});

这是位于resolveHomeTeam服务中的Resolve函数:

function resolveHomeTeam()
{
    var promises = [];
    promises.push($q.defer());
    UserService.team('me', function(data)
    {
        promises[0].resolve(data);
    }, function()
    {
        promises[0].reject();
    });

    return $q.all(promises);
}

正如你在这种情况下所看到的那样,我只是将一个诺言推入数组中,我确信它已经被解决了。

由于唯一的承诺已经解决,$q.all()返回的承诺是否也应该得到解决?不应该将promiseData数据注入SegmentHomeTeamCtrl控制器吗?

如果我尝试在promiseData控制器内输出SegmentHomeTeamCtrl,我会得到整个承诺,包含服务器购买返回的实际数据,原因是我无法访问它。

2 个答案:

答案 0 :(得分:2)

您几乎正在做的事情正确:您正在返回由$q.all生成的承诺,并且您将在resolve中进一步返回该承诺。

错误是你没有创建一个promises数组,而是你将一个延迟对象推入数组。

所以,改变它:

var promises = [];
var teamDefer = $q.defer();
promises.push(teamDefer.promise);

UserService.team('me', function(data)
{
   teamDefer.resolve(data);
}, function()
{
   teamDefer.reject();
});

然后你可以返回$q.all()(和你一样):

return $q.all(promises);

略偏离主题

在我看来,

promiseData被错误地命名,可能表示存在误解。您应该将变量命名为您将获得的结果的名称。这将被注入您的控制器,不管它是否来自承诺。因此,最好将它命名为team(或类似的东西)

答案 1 :(得分:2)

您的代码的问题在于您将延迟放入数组中,而不是承诺。

就此而言,延期很快就会过时了。做出承诺(与ES6 API一致)的首选方法是使用promise constructor

function resolveHomeTeam() {
    var promises = [];

    promises.push($q(function (resolve, reject) {
        UserService.team('me', resolve, reject);
    }));

    return $q.all(promises);
}

请注意这也使您的代码更加清晰。

如果你想:

,你也可以把这个全部合并成一个陈述
function resolveHomeTeam() {
    return $q.all([
        $q(function (resolve, reject) {
            UserService.team('me', resolve, reject);
        })
    ]);
}