Reputation: 165
I have a simple question: what's the best ('cleanest', 'scaleable') path one should go when it comes to interact between (let's say) two controllers. Would that be to define a service and watch that service's return-value in order to react?
I setup a simple example here, where I watch the service's current value:
$scope.$watch(
function() {
return myService.getValue();
},
function(newVal) {
$scope.value1 = newVal;
});
and update that service's value when one of the buttons is clicked.
Can this be done better, smaller, cleaner somehow? What's the best practice here?
Cheers.
Upvotes: 2
Views: 3772
Reputation: 14037
This is the best way to communicate b/w the controller sharing same data via sevice but it is limited b/w controllers having the same service:-
Instead you can also choose to broadcast events that are captured by other controllers and change that data accordingly this way is more scaleable but not clean :-)
Sender ctrl :-
$rootScope.$broadcast('update', 'Some data'); //method that lets pretty much everything hear it even $scope too.
or
$rootScope.$emit('update', 'Some data');// only lets other $rootScope listeners catch it
Listen Ctrl :-
$rootScope.$on('update', function (event, data) {
console.log(data); // 'Some data'
});
Upvotes: 1
Reputation: 5270
Your case is trying to share data between controllers, rather than watch service's value in controllers, I think directly reference service object to controller's scope is a better way
So your view can be
<pre ng-controller="cntrl1">Value in cntrl1: {{ myService.value }} <button ng-click="update('value1')">Change to 'value1'</button></pre>
<pre ng-controller="cntrl2">Value in cntrl2: {{ myService.value }} <button ng-click="update('value2')">Change to 'value2'</button></pre>
and change your controllers to
app.controller('cntrl1', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
app.controller('cntrl2', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
Just as @squiroid points out, you can use $broadcast
to broadcast events to any controllers who is monitoring targeted events.
Please note here, you'd better not use $rootScope.$broadcast + $scope.$on
but rather $rootScope.$emit+ $rootScope.$on
as $broadcast
event will bubble down through all descendant scopes, which might lead to serious performance problems.
Upvotes: 3