我是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调用本身,这使得分离代码似乎不值得。
答案 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);
});
};
但我猜控制器是“胖”的,也不确定包含影响其范围属性的代码的控制器有什么问题。通过传递范围,您使服务依赖于控制器,或者至少是范围/对象上的一组属性,这会违背关注点。
在这种情况下,服务的作用是获取数据并以某种方式返回它,但服务角色不应该是修改控制器属性。