我试图弄清楚如何处理返回http响应的绑定方法的成功和错误。
我正在尝试将工厂方法绑定到控制器,因此我可以从视图中调用它。此方法将尝试通过http请求将项目添加到购物车。如果失败,则被调用的方法将返回false,但如果成功则返回http响应。
我希望能够以某种方式将成功或错误回调添加到绑定方法。这可能吗?
汽车控制器
// Controller to display cars page
app.controller('carsController', function($scope, $rootScope, inventoryFactory) {
// Function that will fetch JSON and save all necessary data for us to use
function init() {
// Bind these method calls to our cart factory
// Allow method to be called from the view
$scope.addToCart = userFactory.addToCart;
// Get list of items in car category
inventoryFactory.getItems('cars').success( function(data) {
$scope.items = data;
});
}
init();
});
userFactory
// Add item of given ID to shopping cart
factory.addToCart = function(itemID) {
// Validate our user / token
data = factory.getUserToken();
if (data === false) {
return false;
}
req = {
method: 'PUT',
url: 'routes.php/api/shoppingcart/' + itemID,
headers: {
'X-Api-Token': data.apiToken,
'UserID': data.userID
}
};
return $http(req);
};
答案 0 :(得分:1)
你正在做的事情会奏效,但我会建议你做一些改变。
首先,直接绑定可能会导致问题。如果您的工厂方法在任何时候都需要调用this
,它将丢失它,因为this
变为$scope
而不是工厂返回的对象。
$scope.addToCart = userFactory.addToCart; // addToCart will have "this" be of $scope
您可以通过代理或包装来保留它:
$scope.addToCart = function(id) {
return userFactory.addToCart(id);
};
保证工厂内的addToCart
具有this
的正确上下文。
其次,虽然你可以做你想做的事情,但如果你要返回一个承诺(如$http()
那样),那么有时返回false并且有时返回一个promise会导致代码混乱和测试困难。您可能最好总是返回承诺并在必要时拒绝承诺:
var defer, ret;
data = factory.getUserToken();
if (data === false) {
defer = $q.defer();
defer.reject();
ret = defer.promise;
} else {
req = {
method: 'PUT',
url: 'routes.php/api/shoppingcart/' + itemID,
headers: {
'X-Api-Token': data.apiToken,
'UserID': data.userID
}
};
ret = $http(req);
}
return ret;
这样你总是有一个承诺,并且可以随时
addToCart(25).then(function(){/* success */),function(){/* failure */});
如果您需要进行错误处理,可能需要在控制器内处理它。因此,如果您的模板是:
<button ng-click="addToCart(item.id)">Click me!</button>
然后您的控制器addToClick可能是:
$scope.addToCart = function(id) {
userFactory.addToCart(id).then(function(results){
// indicate success on the screen by changing some scope var, e.g.
$scope.message = "Successfully added to cart";
},function(err){
// indicate error on the screen by changing some scope var, e.g.
$scope.message = "Problem adding to cart: "+err;
});
};