Reputation: 1
I want to change ng-show in another controller than ng-show is.
myApp.controller('popupCtrl', function() {});
myApp.controller('changePopup', function($rootScope){
// now i wanna show my Ppopup
$rootScope.popup = true;
});
<div ng-controller="popupCtrl">
<div ng-show="popup">
Popuptext
</div>
</div>
But this doesn't work... How can I fix it? Thanks!
Upvotes: 0
Views: 1081
Reputation: 21005
Here is a working demo for you - sorry I changed the controller names, but I am sure you will be able to build on this. Good luck
angular.module('myApp', [])
.controller('c1', function($scope) {
// now i wanna show my Ppopup
$scope.popup = false;
$scope.$on('popup', function() {
$scope.popup = true;
});
})
.controller('changepopup', function($rootScope, $scope) {
// now i wanna show my Ppopup
$scope.clicker = function() {
$rootScope.$broadcast('popup')
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="c1">
<div ng-show="popup">
Popuptext
</div>
</div>
<button ng-controller="changepopup" ng-click="clicker()">Click me</button>
</div>
Upvotes: 0
Reputation: 908
One way to solve this is to use $rootScope.$broadcast
Here is an example: http://plnkr.co/edit/EmJnZvXFRWv6vjKF7QCd
var myApp = angular.module('myApp', []);
myApp.controller('popupCtrl', ['$rootScope', '$scope', function($rootScope,$scope) {
$scope.popup = false;
$rootScope.$on('changePopup', function(event, data) {
$scope.popup = !$scope.popup;
});
}]);
myApp.controller('changePopup', ['$rootScope', '$scope', function($rootScope, $scope) {
$scope.changePopup = function() {
$rootScope.$broadcast('changePopup', 'data could be sent here');
}
}]);
View:
<div ng-controller="popupCtrl">
<div ng-show="popup">
Popuptext
</div>
<div ng-controller="changePopup">
<button ng-click="changePopup()">Change the popup</button>
</div>
Using a service/factory is a better solution for cross controller communication if you are working on a large application, but for a smaller app I would say using $broadcast, $emit and $on is sufficient.
Upvotes: 0
Reputation: 14417
So first thing, you should never add to the $rootScope
or change it in anyway. It has been optimised by the angular team.
Second thing, there is no need to involve the $rootScope
.
Here is a demo showing how to communicate across two controllers.
The key is the event aggregator pattern:
Communicator.register(function (newValue) {
vm.value = Communicator.value;
});
I created a function in the Communicator
to register a callback function. The aim is that when a value gets changed the callback function is fired off. I.e. an event is triggered (change event).
The second key part is fire that change event off:
Communicator.change(!Communicator.value);
Here we pass through to the change
function a new value which will do two things:
By implementing this pattern, we can minimise the extent to which we communicate around our application ($rootScope
can have a tendency to traverse the scope heirarchy when you $broadcast
).
Now we can follow more closely the principle of single responsibility. Our class is aptly named in its current scope, when we look at this factory we can tell it is supposed to "communicate".
Finally, with a global event aggregator pattern ($rootScope
) it is far more difficult to keep track of where these events are being broadcast from, and where they'll end up. Here we don't have that issue
Upvotes: 3