2014-07-17 37 views
0

我在AngularJS的世界新的,和我面臨着一個有趣的問題:交換數據AngularJS電話

我創建了一個角廠家服務,作爲服務代理工作的REST我正在調用服務。 我的服務代理看起來像這樣:

angular.module('myApp').factory('myService', ['$http', function($http) { 

    var baseAddr = "http://myservice.com"; 
    var token = "secure_identifier"; 

    var MyService = { 
     doRequest: function(method, path, token, postData) { 
      return $http({method: method, url: baseAddr+path, headers: {....}, data:postData }); 
     } 
    } 

    return { 

     GetGroupUsers: function(id) 
     { 
      return MyService.doRequest('GET', '/api/groupusers/'+id+'.json', token, null); 
     }, 
     GetUser: function(id) 
     { 
      return MyService.doRequest('GET', '/api/users/'+id+'.json', token, null); 
     } 
    } 
}]); 

所以GetGroupUsers返回用戶ID-S屬於給定的組中,和的getUser返回 指定成員的屬性(例如電子郵件地址的陣列,全名,用戶名,出生日期)。 我想要的是查詢一個組(獲取該組中的userid-s),並在GetUser(userid)方法的幫助下將用戶的名稱附加到數組項 。 我有一個控制器,其中我通過我的代理服務來查詢這個服務。這裏是控制器的相關部分:

//... 
MyService.GetGroupUsers(GroupId).then(function(userlist) 
{ 
    //userlist is an array of a complex object that consists of userId-s and groupId-s 
    //Suppose that it looks like this: 
    // [ {uid: 1, groupId: 1}, {uid: 2, groupId: 1}, {uid: 3, groupId: 1},...,.. ] 
    $scope.groups = userlist.data; 

    //but i need to attach for every item in the array the name of the selected user 
    // [ {uid: 1, groupId: 1,username: 'Alga Rithem'}, {uid: 2, groupId: 1, username:'Anna Nimmity'}, {uid: 3, groupId: 1, username:'Anna Conda'},...,.. ] 

    //So I iterate over the userlist 
    for (var i = 0; i < userlist.data.length; i++) 
    { 
     MyService.GetUser(userlist.data[i].uid). 
      then(function(user) 
      { 
       //And here is the problem I'm facing with: 
       //The value of variable "i" becomes obsolate, because GetUser call is async to the for-loop 
       // when the "then" "callback" executes, the loop may has been finished already! 
       //So I dont really know, where to put the value I've just received 
       //I need that value of i, what it was when i called the service!    
       $scope.groups[i].name = user.data.name; //So this is WRONG! 
      }); 
    } 
}); 

//... 

我解決了這個問題,一個小黑客: 我延長了的getUser(用戶名)與一個參數的PARAMETERLIST到的getUser(用戶名,標籤)。在這個標籤中,我可以把任何我想要 檢索回調。

所以我修改我的代碼一點點:

修改控制器代碼:

//... 

MyService.GetGroupUsers(GroupId).then(function(userlist) 
{  
    $scope.groups = userlist.data; 

    for (var i = 0; i < userlist.data.length; i++) 
    { 
     MyService.GetUser(adat.data[i].uid). 
      then(function(user) 
      {     
       $scope.groups[parseInt(user.config.tag)].name = user.data.name; //This Works fine! 
      }); 
    } 
}); 

//Service proxy 

doRequest: function(method, path, token, postData,tag) { 
      return $http({method: method, url: baseAddr+path, headers: {....}, data:postData }); 
     } 
//... 

GetUser: function(id, tag) 
     { 
      return MyService.doRequest('GET', '/api/users/'+id+'.json', token, null,tag); 
     } 

現在我可以在我的控制器檢索我有效的,過去值我的問題是:這個解決方案在技術上是否正確?這樣的問題的最佳做法是什麼? AngularJS有這個工具嗎?

ps:修改REST服務API以返回用戶名也不是這種情況下的解決方案。

在此先感謝

+0

如果你的API很安靜,可以考慮使用'$ resource',這使得事情變得更容易。另外,你可以顯示所有信息'GetUser'完全返回嗎? – Pak

+0

讓我們假設GetUser返回一個像這樣的JSON對象: 「{ 」id「:9, 」email「:」myemail @ mycompany。com「, 」username「:」mynickname「 }」 $ resource會讓我更容易嗎?無論如何,我需要「加入」這些對象。這不正確嗎? – bkotyik

回答

0

您可以使用,而不是一個for環路關閉一個.forEach遍歷i

userlist.data.forEach(function(user, i){ 
     MyService.GetUser(user.uid). 
      then(function(user) 
      { 
       $scope.groups[i].name = user.data.name; //So this is WRONG! 
      }); 
    } 

或者你可以創建一個映射與.map和使用$q.all使所有更新的曾經:

$q.all(userlist.data.map(function(user){ 
     return MyService.GetUser(user.uid)) 
}).then(function(users){ 
     // assign to scope, users is an array here and you can use indices 
}); 

儘管真實和實際的解決方法是不要讓n用戶致電n用戶,而是創建一種方法,該方法接受服務器上的多個UID並一次爲它們提取所有數據,因爲它將減少系統的負載並提高執行速度,因爲它不會導致往返和http請求。

+0

感謝您的回答。你的第一個例子不會減慢網頁的加載時間?我的意思是forEach使服務調用同步,所以控制器將等待,直到forEach完成,這可能非常耗時。 在您的第二個解決方案中,我如何檢索標記?您能否將我與這種數據映射相關的文章鏈接起來?我真的不知道這件事。謝謝。 – bkotyik

+0

@bkotyik它的做法是'.forEach'而不是'for'不會讓魔法變成同步的,它只是同步地進行調用(注意不同之處,調用仍然是異步的)。在第二個示例中,您可以通過將'users [i]與$ scope.groups [i]'匹配來檢索索引,那麼您就擁有了整個數組。儘管如此,你的解決方案確實改變了後端API。 –

+0

好的,明白了。謝謝! – bkotyik