2016-08-12 37 views
1

我遇到問題,無法將服務返回值分配給變量。我有兩個控制器(AddProject和EditProject),並且這個功能在它們兩個中,並且我想提供一個服務來避免重複代碼。操縱Promise中的數據並將其返回到服務函數中 - AngularJS

 ... 
     .service("UserService", function($http) { 
     var allUsers; 
     var usersPromise = $http.get("/users"); 
     usersPromise.then(
      function(response) { 
       allUsers = response.data.map(function(user) { 
        user._lowername = user.name.toLowerCase(); 
        return user; 
       }); 
       console.log(allUsers) //It prints the object array 
       return allUsers; 
      }, 
      function(error) { 
       console.log(error); 
       return error; 
      }); 

     this.AllUsers = function() { 
      return allUsers; 
     } 
    }) 

而且在我的控制器我有一個變量: (假設所有需要注射作了)

self.AllUsers = UserService.AllUsers(); //it is undefined 

我試圖用$ Q但它得到未定義過。

+0

這哪裏是控制器分配發生了什麼?你確定服務承諾在這項任務之前已經解決了嗎? – Ryan27

+0

難道你不能直接將承諾退還給控制器,讓他們處理分辨率? – noKid

+0

因爲調用方法時'var allUsers'是'undefined'!你應該回報一個承諾。 – estus

回答

2

使用promise的主要原因是處理異步調用(比如你的$ http.get()),但是你似乎試圖以同步的方式使用它。您的服務應該原封不動地返回的承諾,那麼你的控制器應叫它做什麼,就需要把它解決了當:

.service("UserService", function($http) { 
    var allUsers; 
    var usersPromise = $http.get("/users"); 
    usersPromise.then(
      function(response) { 
       allUsers = response.data.map(function(user) { 
        user._lowername = user.name.toLowerCase(); 
        return user; 
       }); 
       console.log(allUsers) //It prints the object array 
       return allUsers; 
      }, 
      function(error) { 
       console.log(error); 
       return error; 
      }); 

    this.AllUsers = function() { 
     return usersPromise; 
    }; 
}); 

....

UserService.AllUsers().then(function(users) { 
    self.AllUsers = users; 
}); 
+0

這樣做的問題是所有對AllUsers()的調用都會執行新的服務器調用。基於這個問題,OP似乎只想打一次電話。 – mcgraphix

1

有可能返回自灌從異步函數稍後將填充值的數組:

... 
    .service("UserService", function($http) { 
    var allUsers = []; 
    var usersPromise = $http.get("/users"); 
    usersPromise.then(
     function(response) { 
      var result = response.data.map(function(user) { 
       user._lowername = user.name.toLowerCase(); 
       return user; 
      }); 
      angular.copy(allUsers, result); 
     }, 
     function(error) { 
      console.log(error); 
      return error; 
     }); 

    this.AllUsers = function() { 
     return allUsers; 
    } 
}) 

angular.copy不改變參考陣列填充時它,則返回空數組被更新自動在視野中。

這個技巧特別適用於ngResource $resource

+0

我會檢查一下。 –

0

部分解決方案(我相信有一個最佳解決方案)。

.service("UserService", function($http) { 
    this.AllUsers = function() { 
     return $http.get("/users"); 
    } 
}) 

我創建的控制器之外的功能:

function mapUsers(userResponse){ 
    return userResponse.data.map(function(user) { 
     user._lowername = user.name.toLowerCase(); 
     return user; 
    }); 
} 

而在兩個控制器我稱之爲:

UserService.AllUsers().then(function(response) { 
      self.AllUsers = mapUsers(response); 
     }); 
+1

'mapUsers'輔助函數不是很好。UserService是它的工作,它是它的數據和操作它的責任,把它看作MVC模型。如果在應用程序中使用了映射和未映射的用戶數組,則可以使用兩種方法而不是一種方法。 – estus

+1

我同意estus。這樣,每個可能調用'UserService.allUsers()'的代碼都需要知道'後面是什麼',並且需要通過應用'mapUsers()'來格式化結果。我會這樣寫:'return $ http.get(「/ users」)。then(response => response.data.map(user =>(user._lowername = user.name.toLowerCase(),user) ))'唯一的事情現在已經改變,相比你最初的嘗試,是調用代碼接收'Promise '而不是'allUsers' – Thomas

+0

謝謝@Thomas工作得很好! –

相關問題