AngularJS嵌套$ http调用

时间:2014-09-19 18:13:35

标签: angularjs

我试图编写一个工厂,从两个来源获取数据并使用一个来源扩展另一个对象中的数据。

app.factory('information', ['$http', '$q', 'players', 'matches', function($http, $q, players, matches) {
    return {
        // Returns all matches and players including extra parsing
        get: function() {
            return players.get().success(function(data) {
                players = data;

                matches.get().success(function(data) {
                    matches = data;

                    for ( match in matches ) {
                        matches[match].a_player1 = players.filter(function(player) { return player.username == matches[match].a_player1 })[0];
                        matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0];
                        matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0];
                        matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0];
                        console.log(matches)
                    }

                    return matches;
                });
            });
        },
    }
}]);

matches.get()players.get()对API的简单GET请求都是这样的:

app.factory('players', function($http) {
    return {
        get: function() {
            return $http({
                method: 'GET',
                url: '/players',
            });
        },
    }
});

但是上面的代码(当然)返回players对象,而我希望它在与matches对象结合后返回players对象。

有关如何执行此操作的任何提示?

2 个答案:

答案 0 :(得分:5)

该函数不会返回任何内容,因为您无法直接从异步操作返回值,无论是返回promise还是使用回调。但我认为你要找的是$q.all

return {
        // Returns all matches and players including extra parsing
        getEverything: function() {

        var getPlayers= $http({
            method: 'GET',
            url: '/players',
        });
        var getMatches= $http({
            method: 'GET',
            url: '/matches',
        });

           return $q.all([getPlayers,getMatches]);
        }
}

用法:

getEverything().then(function(data){
   var players=data[0].data;
   var matches=data[1].data;
})

编辑:

不相关,但要把它搬回工厂:

getEverything: function() {
            var getPlayers= $http({
                method: 'GET',
                url: '/players',
            });
            var getMatches= $http({
                method: 'GET',
                url: '/matches',
            });
            return $q.all([getPlayers,getMatches]);
},
getEverythingMapped:function(){
 var deferred = $q.defer();
 this.getEverything().then(function(data){
       var players=data[0].data;
       var matches=data[1].data;
//do as many loops on either result set as you like
                for ( match in matches ) {
                    matches[match].a_player1 = players.filter(function(player) { return   player.username == matches[match].a_player1 })[0];
                    matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0];
                    matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0];
                    matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0];
                    console.log(matches)
//use of a promise here allows us top use this method using -then, we need to so this since we're
//waiting for the result of an async server call before we can loop through players and matches
                     deferred.resolve(matches);
                }


 }
}

现在您将在控制器中使用上述方法:

information.getEverythingMapped().then(function(matches){
 console.log(matches);
})

答案 1 :(得分:2)

根据$http的文档,此服务返回一个承诺。所以在这种情况下不需要$ q服务它可以简单地写成:

app.factory('information', ['$http', 'players', 'matches', function($http, players, matches) {
    return {
        // Returns all matches and players including extra parsing
        get: function(callback) {
            players.get().then(function(playersData) {
                matches.get().then(function(matchesData) {
                    matches = matchesData;
                    players = playersData;
                    for ( match in matches ) {
                        matches[match].a_player1 = players.filter(function(player) { return player.username == matches[match].a_player1 })[0];
                        matches[match].a_player2 = players.filter(function(player) { return player.username == matches[match].a_player2 })[0];
                        matches[match].b_player1 = players.filter(function(player) { return player.username == matches[match].b_player1 })[0];
                        matches[match].b_player2 = players.filter(function(player) { return player.username == matches[match].b_player2 })[0];
                        console.log(matches)
                    }
                    callback(matches);
                });
            });
        },
    }
}]);

并在控制器中调用如下信息:

information.get(function(data){
    console.log(data);
});