如何在绑定方法(控制器,工厂)上调用成功或错误

时间:2014-12-01 07:13:09

标签: angularjs

我试图弄清楚如何处理返回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);
};

1 个答案:

答案 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;
  });
};