0

i have seven div tags each

<div style="width:200px;height:100px" ng-controller="civCntlr">
amark
  • 71
  • 8

4 Answers4

1

You can use $rootScope.$broadcast + $rootScope.$on to communicate between controllers. For example,

var commApp = angular.module('CommApp', []);

commApp.controller('firstDivController', function($scope, $rootScope) {
  $scope.class = "blue";
  $scope.click = function() {
    $rootScope.$broadcast("selected", "blue");
    if ($scope.class === "blue") {
      $scope.class = "active";
    }
  };
  $rootScope.$on('selected', function(event, data) {
    if (data !== "blue")
      $scope.class = "blue";

  });
});

commApp.controller('secDivController', function($scope, $rootScope) {

  $scope.class = "green"
  $scope.click = function() {
    $rootScope.$broadcast("selected", "green");
    if ($scope.class === "green") {
      $scope.class = "active";
    }
  };
  $rootScope.$on('selected', function(event, data) {
    if (data !== "green")
      $scope.class = "green";
  });
});

commApp.controller('thirdDivController', function($scope, $rootScope) {

  $scope.class = "red"
  $scope.click = function() {
    $rootScope.$broadcast("selected", "red");
    if ($scope.class === "red") {
      $scope.class = "active";
    }
  };
  $rootScope.$on('selected', function(event, data) {
    if (data !== "red")
      $scope.class = "red";
  });
});

commApp.controller('lastDivController', function($scope, $rootScope) {

  $scope.class = "black"
  $scope.click = function() {
    $rootScope.$broadcast("selected", "black");
    if ($scope.class === "black") {
      $scope.class = "active";
    }
  };
  $rootScope.$on('selected', function(event, data) {
    if (data !== "black")
      $scope.class = "black";
  });
});

You can broadcast and listen on every controller like above.

However, just applying class is only your requirement, you can add and remove class dynamically.

$scope.click = function() {
    angular.element(document.getElementsByClassName('active')).removeClass('active');
    angular.element(document.getElementsByClassName('blue')).addClass('active');
  };
Pitchai P
  • 1,317
  • 10
  • 22
  • can you add a fiddle or something – amark Nov 30 '15 at 07:05
  • passing the color name as the data part of $broadcast and then using it to reset the div to previous state , right @pitchai – amark Nov 30 '15 at 07:28
  • However, if applying class is only your requirement, I would suggest, add class active on click and remove all "active" classes first before adding class "active". Pls refer: http://plnkr.co/edit/Qeoa0uMgz69yNvjdEvkV?p=preview – Pitchai P Nov 30 '15 at 07:52
1

It is always good to use service to communicate between controllers. I have done a small demo to show how to communicate between controllers using a service.

When ever data/some flag is changed then save it to the service. Your service should broadcast the changes to all the controllers. You then get the data from the service and change the view accordingly.

angular.module('myApp', []);

angular.module('myApp').controller('firstDivController', function($scope, service) {

  $scope.divColor = (service.getId() == 'one' ? "green" : "red");

  $scope.click = function() {
    alert('Ctrl One');
    service.setId('one');
  };

  $scope.$on('id', function() {
    $scope.divColor = (service.getId() == 'one' ? "green" : "red");
  });

});

angular.module('myApp').controller('secDivController', function($scope, service) {
  $scope.divColor = (service.getId() == 'two' ? "green" : "red");
  $scope.click = function() {
    alert('Ctrl two');
    service.setId('two');
  };

  $scope.$on('id', function() {
    $scope.divColor = (service.getId() == 'two' ? "green" : "red");
  });
});

angular.module('myApp').service('service', function($rootScope) {
  var divId = 'one';

  this.getId = function() {
    return divId;
  };

  this.setId = function(id) {
    divId = id;
    this.broadcastId();
  };

  this.broadcastId = function() {
    $rootScope.$broadcast('id');
  };

});

Update:

After suggestion from @Cyril Gandon I have updated the code by removing the broadcast.

Working Plunker

Amarnath
  • 8,736
  • 10
  • 54
  • 81
  • any specific reason to use services over broadcasts for sommunication between controllers ?? – amark Nov 30 '15 at 08:28
  • broadcast is not a good idea, it will lead your code to spaghetti code, it is difficult to debug, it is not self contained, not modular. Use services, instead. Angular2 will not let you have broadcast in your code. On the other hand, in this answer, `$scope.$on` is basically the same as broadcast, this is still wrong. – Cyril Gandon Nov 30 '15 at 08:33
  • @CyrilGandon Thanks for the info. I have updated my code. I have question, when I specify `ng-class` as a data varioable instead of method then if any controller changes the value in the service the view is not refreshing unless I use broadcast. But when I use method for ng-class then it is working fine. So can you tell me why it is not working without broadcast? – Amarnath Nov 30 '15 at 10:20
0

Use ng-style and then use condition (ternary operator) inside ng-style

Rohan Kawade
  • 453
  • 5
  • 18
0

You should use a service when you need controller communicating.

Read this article on anti-patterns:

Only use .$broadcast(), .$emit() and .$on() for atomic events Events that are relevant globally across the entire app (such as a user authenticating or the app closing). If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs $scope.$watch() should replace the need for events Injecting services and calling methods directly is also useful for direct communication Directives are able to directly communicate with each other through directive-controllers

// Code goes here
angular.module('myApp', []);

angular.module('myApp').service('activeService', function($rootScope) {
  var activeId = 'one';
  
  this.isActive = function(id) {
    return activeId == id;
  };
  this.setActive = function(id) {
    activeId = id;
  };  
});

angular.module('myApp').controller('firstDivController', function($scope, activeService) {
  var id = 'one';
  $scope.click = function() {
    activeService.setActive(id);
  };
  
  $scope.getDivColor = function() {
    return activeService.isActive(id) ? 'active' : 'blue';
  };
    
});

angular.module('myApp').controller('secDivController', function($scope, activeService) {
  var id = 'two';
  $scope.click = function() {
    activeService.setActive(id);
  };
  
  $scope.getDivColor = function() {
    return activeService.isActive(id) ? 'active' : 'green';
  };
});

angular.module('myApp').controller('thirdDivController', function($scope, activeService) {
  var id = 'three';
  $scope.click = function() {
    activeService.setActive(id);
  };
  
  $scope.getDivColor = function() {
   return activeService.isActive(id) ? 'active' : 'red';
  };
});

angular.module('myApp').controller('lastDivController', function($scope, activeService) {
  var id = 'last';
  $scope.click = function() {
    activeService.setActive(id);
  };
  
  $scope.getDivColor = function() {
    return activeService.isActive(id) ? 'active' : 'black';
  };
 
});
.green {
    background-color: green;
}
.blue {
    background-color: blue;
}
.red {
    background-color: red;
}
.black {
    background-color: black;
}
.active{
 background-color: yellow ;
}
<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
  </head>

  <body>
      <div style="width:200px;height:30px" 
           ng-controller="firstDivController" 
           ng-click="click()" 
           ng-class="getDivColor()">
      <center>Hello , your in first box</center>
     </div>
    
     <div style="width:200px;height:30px" 
             ng-controller="secDivController"
             ng-click="click()" 
             ng-class="getDivColor()">
      <center>Hello , you are in second box</center>
     </div>
    
     <div style="width:200px;height:30px" 
             ng-controller="thirdDivController" 
             ng-click="click()" 
             ng-class="getDivColor()">
      <center>Hello , you are in third box</center>
     </div>
    
     <div style="width:200px;height:30px" 
             ng-controller="lastDivController" 
             ng-click="click()" 
             ng-class="getDivColor()">
      <center>Hello , you are in last box</center>
     </div>
  </body>
</html>
Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122