Search code examples
javascriptangularjsangularjs-scopecontrollers

How to set a variable in different controller in AngularJS?


I'd like to do simple notifications in angular. Here is the code I've written. http://pastebin.com/zYZtntu8 The question is: Why if I add a new alert in hasAlerts() method it works, but if I add a new alert in NoteController it doesn't. I've tried something with $scope.$watch but it also doesn't work or I've done something wrong.

How can I do that?


Solution

  • Check out this plnkr I made a while back

    http://plnkr.co/edit/ABQsAxz1bNi34ehmPRsF?p=preview

    I show a couple of ways controllers can use data from services, in particular the first two show how to do it without a watch which is generally a more efficient way to go:

    // Code goes here
    
    angular.module("myApp", []).service("MyService", function($q) {
      var serviceDef = {};
      //It's important that you use an object or an array here a string or other
      //primitive type can't be updated with angular.copy and changes to those
      //primitives can't be watched.
      serviceDef.someServiceData = {
        label: 'aValue'
      };
      serviceDef.doSomething = function() {
        var deferred = $q.defer();
    
        angular.copy({
          label: 'an updated value'
        }, serviceDef.someServiceData);
    
        deferred.resolve(serviceDef.someServiceData);
        return deferred.promise;
      }
      return serviceDef;
    }).controller("MyCtrl", function($scope, MyService) {
      //Using a data object from the service that has it's properties updated async
      $scope.sharedData = MyService.someServiceData;
    }).controller("MyCtrl2", function($scope, MyService) {
      //Same as above just has a function to modify the value as well
      $scope.sharedData = MyService.someServiceData;
      $scope.updateValue = function() {
        MyService.doSomething();
      }
    }).controller("MyCtrl3", function($scope, MyService) {
      //Shows using a watch to see if the service data has changed during a digest
      //if so updates the local scope
      $scope.$watch(function(){ return MyService.someServiceData }, function(newVal){
        $scope.sharedData = newVal;
      })
      $scope.updateValue = function() {
        MyService.doSomething();
      }
    }).controller("MyCtrl4", function($scope, MyService) {
      //This option relies on the promise returned from the service to update the local
      //scope, also since the properties of the object are being updated not the object
      //itself this still stays "in sync" with the other controllers and service since
      //really they are all referring to the same object.
      MyService.doSomething().then(function(newVal) {
        $scope.sharedData = newVal;
      });
    });
    

    The notable thing here I guess is that I use angular.copy to re-use the same object that's created in the service instead of assigning a new object or array to that property. Since it's the same object if you reference that object from your controllers and use it in any data-binding situation (watches or {{}} interpolation in the view) will see the changes to the object.