3

As a contrived example, let's say I have an angular controller that looks something like this:

function OverflowController($scope) {

  // initialize the count variable
  $scope.count = 0;

  // pretend the overflow logic is complex and doesn't belong in a filter or view
  var count = parseInt($scope.count);

  if (count < 100) {
    $scope.overflow = "normal";
  }
  else if (count < 200) {
    $scope.overflow = "warning";
  }
  else {
    $scope.overflow = "error";
  }

};

and I have a view that looks like this:

<input ng-model="count">
<p>Count: {{count}}</p>
<p>Overflow? {{overflow}}</p>

How can I bind the overflow property of the scope to the count property in such a way that when the count is updated, the overflow automatically gets updated too?

LandonSchropp
  • 10,084
  • 22
  • 86
  • 149

3 Answers3

4

Use $watch: (http://docs.angularjs.org/api/ng.$rootScope.Scope#$watch)

function OverflowController($scope) {

  // initialize the count variable
  $scope.count = 0;

  $scope.$watch('count', function (count) {
     // pretend the overflow logic is complex and doesn't belong in a filter or view

     if (count < 100) {
       $scope.overflow = "normal";
     }
     else if (count < 200) {
       $scope.overflow = "warning";
     }
     else {
       $scope.overflow = "error";
     }
   });
};
Karen Zilles
  • 7,633
  • 3
  • 34
  • 33
  • Is the view automatically updated? How does Angular know the function passed to `$watch` has updated the `overflow` property? – LandonSchropp Jul 12 '13 at 20:38
  • view is updated automatically. After a watch function runs angular does a digest which checks all of your template values for changes. – Karen Zilles Jul 12 '13 at 20:39
0

A simple way would be to watch it for changes:

  $scope.$watch('count', function(newVal, oldVal) {
    if (!angular.equals(newVal, oldVal)) {
       updateCount();
    }
  });

  function updateCount() {
    var count = parseInt($scope.count);

    if (count < 100) {
      $scope.overflow = "normal";
    }
    else if (count < 200) {
      $scope.overflow = "warning";
    }
    else {
      $scope.overflow = "error";
    }
  }
Terry
  • 14,099
  • 9
  • 56
  • 84
0

just use getOverflow as $scope function:

<div ng-controller="OverflowController">
<input ng-model="count" />
<p>Count: {{count}}</p>
<p>Overflow? {{getOverflow()}}</p>

angular.module('myApp', [])
    .controller("OverflowController", function ($scope) {
    // initialize the count variable
    $scope.count = 0;   
    $scope.getOverflow = function () {
         var count = parseInt($scope.count);
        var overflow = "error";
        if (count < 100) {
           overflow = "normal";
        } else if (count < 200) {
            overflow = "warning";
        }
        return overflow;
    }
});

JSFiddle: http://jsfiddle.net/alfrescian/Gt9QE/

alfrescian
  • 4,079
  • 1
  • 18
  • 20
  • The only issue with doing it this way is that your getOverflow function will be run everytime angular does a digest, which is often. Using a $watch means it will only be run when count changes. – Karen Zilles Jul 12 '13 at 20:54
  • yub, but you doesn't have to add a 2nd watch if an additional property has to be considered to calculate overflow – alfrescian Jul 12 '13 at 20:58
  • 1
    You can just add the property to the same watch. Check out my answer on this question: http://stackoverflow.com/questions/11952579/watch-multiple-scope-attributes-in-angularjs – Karen Zilles Jul 12 '13 at 21:07