2013-01-10 33 views
2

有關於在服務中處理$ http的related question,但我想稍微詳細說明。我想我的控制器能夠使用類似於角$ HTTP API API執行服務電話:

$scope.login = function(user) { 
    securityService.login(user).success(function(data) { 
    $scope.data = data; 
    }).error(function(data) { 
    $scope.error = data; 
    }); 
}; 

這是一個不錯的可讀性API。從表面上看,一切我都需要的服務API中做的是:

return { 
    name : 'User Service', 
    login : function(user) { 
    return $http.post("/api/login", user); 
    } 
}; 

大,它返回的承諾和successerror消息都用。但是......如果我想處理服務中的成功和失敗案例呢?我想維護漂亮可讀的服務API。在這種情況下,也許我想保留用戶,以便我可以公開諸如securityService.currentUser()或`securityService.isLoggedIn()'的方法。

我嘗試了$http.post().then(...)諾言API,但那些返回整個HTTP響應。同樣,我想將HTTP隔離到服務並維護一個類似的具體回調API。

回答

5

你可以使用角度的$q使自己的承諾在login

var deferred = $q.defer(), 
    promise = deferred.promise; 

$http.post("/api/login", user).success(...).error(...) 

return promise; 

在你的服務的$ HTTP承諾的成功/失敗,解決/拒絕你的延期對象。

編輯:

擴大於$http.post

$http.post("/api/login", user).success(function(data) { 
    if (data == "foo") { // success case? 
    deferred.resolve('you logged in!'); 
    } else { 
    deferred.reject('something really bad happened!'); 
    } 
}) 
+0

你能擴展你的例子嗎? – andyczerwonka

+0

當然,對不起,應該包括在第一個例子中。 – wless1

+0

,然後我只是在控制器中使用成功和錯誤,並獲得每種情況下的文本? – andyczerwonka

1

我只是跑一個測試案例,似乎如果我從服務API返回的承諾是這樣的:

return $http.post("/api/login", user).success(...).error(...) 

我也可以在控制器中做同樣的事情:

service.login(user).success(...).error(...) 

並且都被調用,服務第一和控制器第二。那很完美!

+0

當然,承諾可以鏈接。如果您不想將控制器暴露給'$ http'返回的低級細節,而是從您的API中返回更乾淨的東西,那麼您會希望自己承諾。 – wless1

+0

請注意:不要忘記,'.success()。error()'語法不被'$ q'支持,並且被'$ http'模擬(你可以看源代碼如何承諾擴展)。這意味着,如果您返回承諾表單成功/錯誤的回調,那麼'$ q' chaning功能將無法工作。我會建議使用'then(successCb,errorCb)'語法 - 然後您可以從回調中返回其他承諾並獲得一個相當有趣的可鏈接工作流程。 –

+0

你有沒有例子? – andyczerwonka

相關問題