I'm fairly new to Angular.js. I try to keep my code organized, in particular, my controllers thin. My current setup is as follows:
User events get picked up by my controller, eg a button click will invoke $scope.upgrade()
in controller.
$scope.upgrade = function() {
$scope.submitting = true // disable upgrade button
payment.chargeCreditCard($scope);
};
Then the payment
service takes over and does the actual work which involves making AJAX call to backend. In my payment service module, the code is something like:
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
});
};
My question is, it feels wrong to pass $scope
from controller to service. Services should be independent and should not care about things like setting the value of $scope.error
and $scope.submitting
.
What is the Angular way of doing this?
== UPDATE ==
So one solution I came up with is make the AJAX call in the service but return the result to controller. Something like:
// in controller
$scope.upgrade = function() {
// call service...
var response = payment.chargeCreditCard($scope);
response
.success(function() {
// ...
})
.error(function() {
// set $scope.error etc...
});
};
But then the controller is still pretty fat and the only thing that's in service is just the AJAX call itself which makes it seem not very worthwhile to separate the code.
Return the result of the $http
call in the service and use the success
handler in your controller.
Controller
$scope.upgrade = function() {
$scope.submitting = true // disable upgrade button
payment.chargeCreditCard().success(function() {
// do stuff
}).error(function() {
// Do other stuff
});
};
Service
payment.chargeCreditCard = function() {
return $http({
method: 'post',
url: endpoint,
data: data
});
};
Another way of doing it if this is not what you are after is using events. So in your service have the $rootScope
has dependencies and use the $broadcast
method.
Controller
$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
});
};
Service
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);
});
};
But I guess the controller is as "fat", also not sure what is wrong with the controller containing the code that affect the property of its scope. By passing the scope you are making the service dependent on the controller or at least a set of properties on a scope/object which kind of go against the separation of concern.
The role of the service in this case would be to get the data and return it, one way or the other, but the service role should not be to modify controller properties.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.