所以,我正在尝试使用AngularJS,并且,作为练习,我想我会使用Steam API创建一个简单的应用程序。我做了一个简单的Spring Boot Rest服务,它为Steam API提供反向代理服务,以便可以转发某些调用。此时有两个动作:
/user/
提供了蒸汽ID列表。
/user/:id/games
提供以下api的输出:
http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=MY_STEAM_KEY&steamid=STEAM_ID&format=json
以下列格式返回答案:
{
"response":{
"game_count":3,
"games":[
{
"appid":70000,
"playtime_forever":0
},
{
"appid":550,
"playtime_forever":0
},
{
"appid":274900,
"playtime_forever":0
}
]
}
}
我想要实现的是从这个json对象中提取games
数组,并将其附加到正确的用户。我想为所有用户这样做。通过定义以下工厂,我已经使用$ resource对象实现了我想要的东西:
angular.module("SAM.Resources", [])
.factory("UserList", ["$resource",
function ($resource) {
return $resource('/user');
}])
.factory("GamesList", ["$resource",
function ($resource) {
return $resource('/user/:id/games', {
id: '@id'
});
}
]);
然后在我的控制器中使用以下内容:
UserList.query(function(response){
$scope.users = response ? response : [];
for(index=0; index < $scope.users.length; ++index){
user = $scope.users[index];
$scope.users[index].games = GamesList.get({id:user.id});
}
});
这接近我想要的,然而,它会返回以下格式:
{
"id": "76561198119953061",
"name": "Yuri",
"games": {
"response": {
"game_count": 3,
"games": [
{
"appid": 70000,
"playtime_forever": 0
},
{
"appid": 550,
"playtime_forever": 0
},
{
"appid": 274900,
"playtime_forever": 0
}
]
}
}
}
我不想要games.response.games
构造。我试图将其改为:
$scope.users[index].games = GamesList.get({id:user.id}).response.games;
失败的似乎是合乎逻辑的,因为它是一个承诺,并且不会立即包含响应对象。
我也尝试使用像
这样的东西GamesList.get({id:user.id}), function(response){
angular.extend(user, response);
});
确实将响应附加到user
对象,只有user
对象始终是promise解析时数组中的最后一个值。
所以基本上我的问题归结为:如何使用User
列表扩展我的Games
对象?
答案 0 :(得分:2)
您需要稍微改变一下代码:
UserList.query(function(response){
$scope.users = response ? response : [];
for(index=0; index < $scope.users.length; ++index){
user = $scope.users[index];
(function(index, id){
GamesList.get({id: id}, function(response){ // Get the games from the response
$scope.users[index].games = response.response.games;
}));
})(index, user.id)
}
});
在for
循环中,user
不断更改值。当第一个GameList.get
返回一个值时,您的循环将在最后一个用户处。
将IIFE
包裹在一个单独的范围内将这些变量分开。
答案 1 :(得分:1)
for(index=0; index < $scope.users.length; ++index){
user = $scope.users[index];
$scope.users[index].games = GamesList.get({id:user.id}, function(response){
angular.extend(user, response);
}));
}
当您这样做时,用户变量将在每一步都改变。但匿名回调将在稍后执行。所以只使用了最后一个用户。
您可以使用匿名函数作为forEach
的范围:
$scope.users.forEach(function(user) {
$scope.users[index].games = GamesList.get({id:user.id}, function(response){
angular.extend(user, response);
}));
});
如果您想避开user.games.response.games
,则需要以不同的方式合并对象。
$scope.users.forEach(function(user) {
$scope.users[index].games = GamesList.get({id:user.id}, function(response){
user.games = response.games;
user.games_count = response.games_count;
}));
});