0

I have a follow button for a particular user that should change its text to followed after it's clicked and vice versa. This follow button can show up in different modules on the page. When it's clicked, the follow button for this particular users should update in all of these modules. However, the buttons are in different scopes. What is the angular way of making sure the cloned buttons are in the same state?

My current solution is to use an universal jQuery selector to update all the buttons on click.

Allen
  • 91
  • 3

2 Answers2

2

You should store the state in a service.

example:

app.factory('SharedService', function() {
  this.buttonState = null;

  this.setButtonState= function(value) {
    this.buttonState = value;
  }

  this.getButtonState= function() {
    return this.buttonState ;
  }

  return this;
});

Read: AngularJS Docs on services

or check this Egghead.io video

rmuller
  • 1,837
  • 12
  • 12
-1

You can use $rootScope.$broadcast to do this. when any of button gets clicked you fire an event using $rootScope.$broadcast and then listen to it using $scope.$on and toggle the status of buttons. and you can also update state inside the service too, so you can fetch current value later if needed.

See the below example:

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

app.controller('ctrl1', function($scope) {
  $scope.label1 = "First Button";
});

app.controller('ctrl2', function($scope) {
  $scope.label2 = "Second Button";
});

app.controller('ctrl3', function($scope) {
  $scope.label3 = "Third Button";
});

// updating state in service too.
app.service('fButtons', function($rootScope) {
  var buttonState = false;
  this.getCurrentState = function() {
    return buttonState;
  };

  this.updateCurrentState = function() {
    buttonState = !buttonState;
  };
});

app.directive('followButton', function($rootScope, $timeout, fButtons) {

  return {
    restrict: 'E',
    scope: {
      label: '='
    },
    template: '<button ng-click="buttonClick()" ng-class="{red: active}">{{label}}</button>',
    controller: function($scope) {
      $scope.$on('button.toggled', function() {
        $scope.active = !$scope.active;
      });

      $scope.buttonClick = function() {
        fButtons.updateCurrentState();
        $rootScope.$broadcast('button.toggled');
        console.log(fButtons.getCurrentState());
      }
    }
  };

});
.red {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">

  <div ng-controller="ctrl1">
    <follow-button label="label1"></follow-button>
  </div>
  <hr/>
  <div ng-controller="ctrl2">
    <follow-button label="label2"></follow-button>
  </div>
  <hr/>
  <div ng-controller="ctrl3">
    <follow-button label="label3"></follow-button>
  </div>
</div>

see console for service state.

$broadcast docs

jad-panda
  • 2,509
  • 16
  • 22