james February 2016

Angular - compare many old and new values

Using Angular, is it possible to compare an old and new value when it is changed (programmatically, or otherwise)?

I guess what I'm after is functionality similar to ng-change that can be applied to any element and is triggered whenever the value in the expression is updated.

Of course, I could use $scope.$watch on the entire data model, find the individual changed values (and injecting a 'changeDirection' property) but this feels excessive.

Edit: Consider a data model of an array of 500 objects, each with 5 properties, 2 of which are integers that I need to know if they have increased/decreased.

Answers


mccainz February 2016

You can use $watch on dot delimited paths to signify individual properties in the model you wish to watch.

<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>

  <div ng-controller="ctrl">
    <input ng-model="model.name.first" />Update:{{watchVals}}
  </div>
  
  <script>
    var app = angular.module("app", []);
    app.controller("ctrl", ["$scope",
      function($scope) {

        $scope.model = {
          "name": {
            "first": "John",
            "last": "Doe"
          }
        };

        $scope.val = "";
        $scope.$watch("model.name.first", function(newVal, oldVal) {
          $scope.watchVals = oldVal + " -> " + newVal;
        });
      }
    ]);
    angular.bootstrap(document, [app.name]);
  </script>
</body>

</html>


Saeid Doroudi February 2016

i recommend use $watch for watching object changes and you can pass new value and old value to function like this:

$scope.$watch('myObject', function(newValue, oldValue){
    if(!angular.equals(newValue, oldValue)){
       doSomeThing(); 
    }
});


Neel February 2016

There are few key differences between ng-change (angular built in directive) and $watch.

Consider this html markup

<input type=text ng-model=obj.name ng-change="triggerNameChanged()">
  1. Using ng-change would call triggerNameChanged() function only on the actual changes to the input by the user.However Watch are also called in other cases too- right when they’re being defined the first time and on changes made to the value not by the user, e.g. programmatically.

  2. Whenever you write {{}} expression internally a watch is set up to look for changes in your model.

  3. Using ng-change is a bit more performant, since it uses one less watch expression. Since Angular knows it should only call the expression on change events it does not need to keep evaluating it on every digest cycle, as opposed to watch.

  4. By default $watch compares by reference.So If you set the third parameter to true, Angular will instead "shallow" watch the object for changes.

An Example of watch


$scope.$watch('myForm.modified', handler)

in this case handler will be called if some form elements actually contains new data or if it reversed to initial state.you can use modified property of individual form elements to actually reduce amount of data sent to a server .

Post Status

Asked in February 2016
Viewed 3,804 times
Voted 14
Answered 3 times

Search




Leave an answer