我应该在Angular.js中将AJAX调用的响应处理程序代码放在哪里?

时间:2015-06-01 21:27:54

标签: javascript angularjs

我是Angular.js的新手。我试图保持我的代码组织,特别是我的控制器很薄。我目前的设置如下:

用户事件由我的控制器接收,例如单击按钮将调用控制器中的$scope.upgrade()

$scope.upgrade = function() {
  $scope.submitting = true // disable upgrade button
  payment.chargeCreditCard($scope);
};

然后payment服务接管并执行涉及向后端进行AJAX调用的实际工作。在我的支付服务模块中,代码类似于:

payment.chargeCreditCard = function($scope) {
  $http({
    method: 'post',
    url: endpoint,
    data: data
  }).success(function() {
    // do things...
  }).error(function() {
    $scope.error = "Something wrong happened."; // $scope was passed in from controller
    $scope.submitting = false; // Re-enable the button
  });
};

我的问题是,将$scope从控制器传递到服务是错误的。服务应该是独立的,不应该关心设置$scope.error$scope.submitting的价值。

这样做的角度方式是什么?

== UPDATE ==

因此,我提出的一个解决方案是在服务中进行AJAX调用,但将结果返回给控制器。类似的东西:

// in controller
$scope.upgrade = function() {
  // call service...
  var response = payment.chargeCreditCard($scope);

  response
    .success(function() {
      // ...
    })
    .error(function() {
      // set $scope.error etc...
    });
};

但是控制器仍然很胖,而且服务中唯一的就是AJAX调用本身,这使得分离代码似乎不值得。

1 个答案:

答案 0 :(得分:1)

返回服务中$http调用的结果,并使用控制器中的success处理程序。

控制器

$scope.upgrade = function() {
  $scope.submitting = true // disable upgrade button
  payment.chargeCreditCard().success(function() {
    // do stuff
  }).error(function() {
    // Do other stuff
  });
};

服务

payment.chargeCreditCard = function() {
  return $http({
    method: 'post',
    url: endpoint,
    data: data
  });
};

另一种方法是,如果这不是你所追求的是使用事件。因此,在您的服务中,$rootScope具有依赖关系,并使用$broadcast方法。

控制器

$scope.upgrade = function() {

  $scope.submitting = true // disable upgrade button
  payment.chargeCreditCard();

  $scope.$on("chargeCreditCard:success", function(ev, data) {
    // Do stuff
  });

  $scope.$on("chargeCreditCard:error", function(ev, err) {
    // Do other stuff
  });
};

服务

payment.chargeCreditCard = function() {
  return $http({
    method: 'post',
    url: endpoint,
    data: data
  }).success(function(data) {
    $rootScope.$broadcast("chargeCreditCard:success", data);
  }).error(function(err) {
    $rootScope.$broadcast("chargeCreditCard:error", err);
  });
};

但我猜控制器是“胖”的,也不确定包含影响其范围属性的代码的控制器有什么问题。通过传递范围,您使服务依赖于控制器,或者至少是范围/对象上的一组属性,这会违背关注点。

在这种情况下,服务的作用是获取数据并以某种方式返回它,但服务角色不应该是修改控制器属性。