AngularJS $watch vs $watchCollection: which is better for performance?

前端 未结 3 2013
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-30 19:46

For watching an object scope variable, is $scope.$watch with objectEquality set to true OR $scope.$watchCollection better?

For

相关标签:
3条回答
  • 2020-11-30 20:29

    $watch() will be triggered by:

    $scope.myArray = [];
    $scope.myArray = null;
    $scope.myArray = someOtherArray;
    

    $watchCollection() will be triggered by everything above AND:

    $scope.myArray.push({}); // add element
    $scope.myArray.splice(0, 1); // remove element
    $scope.myArray[0] = {}; // assign index to different value
    

    $watch(..., true) will be triggered by EVERYTHING above AND:

    $scope.myArray[0].someProperty = "someValue";
    

    JUST ONE MORE THING...

    $watch() is the only one that fires when an array is replaced with another with the same exact content. For example:

    $scope.myArray = ["Apples", "Bananas", "Orange" ];
    
    var newArray = [];
    newArray.push("Apples");
    newArray.push("Bananas");
    newArray.push("Orange");
    
    $scope.myArray = newArray;
    

    Below is a link to an example JSFiddle that uses all the different watch combinations and outputs log messages to indicate which "watches" were triggered:

    http://jsfiddle.net/luisperezphd/2zj9k872/

    0 讨论(0)
  • 2020-11-30 20:34

    The $watchCollection() function is a sort-of mid-ground between the two $watch() configurations above. It's more in-depth than the vanilla $watch() function; but, it's not nearly as expensive as the deep-equality $watch() function. Like the $watch() function, the $watchCollection() works by comparing physical object references; however, unlike the $watch() function, the $watchCollection() goes one-level deep and performs an additional, shallow reference check of the top level items in the collection.

    see this explanation

    0 讨论(0)
  • 2020-11-30 20:35

    $watchCollection is optimized for vector arrays [] where elements can be push

    and $watch is good for associative arrays objects {}

    $watchCollection will not watch for depth changes, is like watch with objectEquality set to false.

    If you already know to structure of the depth you can optimize like this:

      // ctrl watch ?
      $scope.$watch('filters', function(newVal, oldVal) {
        if(newVal !== oldVal) {
          // call with updated filters
        }
      });
    
      // ctrl watch ?
      $scope.$watch('filters.info', function(newVal, oldVal) {
        if(newVal !== oldVal) {
          // call with updated filters
        }
      });
    
    0 讨论(0)
提交回复
热议问题