2013-07-28 46 views
4

我想知道將$ http調用抽象爲angularjs服務的最佳方式是什麼。我已經做了一些調查,這似乎是最常見的方式:

app.factory('myService', function($http) { 
return { 
    getFoo: function() { 
    return $http.get('foo.json').then(function(result) { 
     return result.data; 
    }); 
    } 
} 
}); 

app.controller('MainCtrl', function($scope, myService) { 
    //the clean and simple way 
    $scope.foo = myService.getFoo(); 
} 

但是這種方法的問題是我無法弄清楚如何做.error什麼。

我更喜歡在我的控制器中有我的.success和.error回調。

有沒有辦法在服務內部抽象http調用,同時在控制器內部維護.error和.success回調?

謝謝。

回答

4

您仍然可以使用成功/錯誤調用。

您突出顯示的方法返回"Promise"對象。承諾的一個好處是它們是可鏈接的。

所以說,你想在你的控制器到$ http請求響應錯誤:

app.factory('myService', function($http) { 
return { 
    getFoo: function() { 
    return $http.get('foo.json').then(function(result) { 
     return result.data; 
    }); 
    } 
} 
}); 

app.controller('MainCtrl', function($scope, myService) { 
    //the clean and simple way 
    $scope.foo = myService.getFoo().then(function(){ 
    //Do something with successful response 
    }, function(){ 
    //Do something with unsuccessful response 
    }); 
} 

注:此以下下一節不再適用。承諾解決後,模板中使用的承諾不再自動解析爲其值。

你也應該明白爲什麼分配$scope.foo在你的模板中工作。 AngularJS具有一定的魔力,可以解決模板中需要的對象的任何承諾。因此,雖然您的模板可能會引用foo.bar並且輸出將是正確的,但背景中實際發生的事情是模板正在等待承諾在渲染該模板部分之前完成。

此外,另一個問題是要記住,如果您處理鏈中某處的錯誤,則會返回拒絕的承諾。

例如:

app.factory('myService', function($http, $q) { 
return { 
    getFoo: function() { 
    return $http.get('foo.json').then(function(result) { 
     return result.data; 
    }, function(result){ 
     //I'm doing something here to handle the error 
     return $q.reject(result); 
    }); 
    } 
} 
}); 

app.controller('MainCtrl', function($scope, myService) { 
    //the clean and simple way 
    $scope.foo = myService.getFoo().then(function(){ 
    //Do something with successful response 
    }, function(){ 
    //Do something with unsuccessful response 
    }); 
} 

如果我們沒有在服務返回拒絕承諾,控制器的「成功」的代碼路徑將運行,而不是拒絕路徑。

+0

謝謝,很好的解釋:-) – andro1d