オブジェクトスコープ変数を監視する場合、$scope.$watch
objectEquality
をtrueに設定OR $scope.$watchCollection
より良い?
のために $scope
オブジェクト変数(15個の属性、ネストされた2レベルの深さなど)が入力要素とng-model
ビューでは、$scope.$watch
objectEquality
はtrue
に設定されていますか?これは避けるべき大きなことですか?
$watchCollection
より良い解決策は?
私は、AngularJSアプリのパフォーマンスを改善するための簡単な勝利を探しています(v1.2.2のままです)。
// ctrl scope var
$scope.filters = {
name: '',
info: {test: '', foo: '', bar: ''},
yep: ''
// etc ...
}
// ctrl watch ?
$scope.$watch('filters', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
}, true);
// or ctrl watch collection ?
$scope.$watchCollection('filters', function(newVal, oldVal) {
if(newVal !== oldVal) {
// call with updated filters
}
});
// view input with ng-model
<input type="text" ng-model="filters.name" />
<input type="text" ng-model="filters.info.test" />
<input type="text" ng-model="filters.yep" />
// etc ...
$watchCollection()
関数は、上記の2つの$watch()
構成の中間に位置します。 Vanillaの$ watch()関数よりも詳細です。しかし、それは深い平等$watch()
関数ほど高価ではありません。$watch()
関数と同様に、$watchCollection()
は物理オブジェクト参照を比較することにより機能します。ただし、$watch()
関数とは異なり、$watchCollection()
は1レベル深くなり、コレクション内の最上位アイテムの追加の浅い参照チェックを実行します。
$ watch()は以下によってトリガーされます:
$scope.myArray = [];
$scope.myArray = null;
$scope.myArray = someOtherArray;
$ watchCollection()は、上記のすべてによってトリガーされます。
$scope.myArray.Push({}); // add element
$scope.myArray.splice(0, 1); // remove element
$scope.myArray[0] = {}; // assign index to different value
$ watch(...、true)は、上記のすべてによってトリガーされます。
$scope.myArray[0].someProperty = "someValue";
もう1つ...
$ watch()は、配列がまったく同じ内容の配列に置き換えられたときに起動する唯一のものです。例えば:
$scope.myArray = ["Apples", "Bananas", "Orange" ];
var newArray = [];
newArray.Push("Apples");
newArray.Push("Bananas");
newArray.Push("Orange");
$scope.myArray = newArray;
以下は、すべての異なるウォッチの組み合わせを使用し、トリガーされた「ウォッチ」を示すログメッセージを出力するJSFiddleの例へのリンクです。
$watchCollection
はベクトルarrays []
要素はプッシュ可能
および$watch
は連想配列オブジェクトに適しています{}
$watchCollection
は深度の変化を監視しません。objectEqualityがfalseに設定された監視のようなものです。
深さの構造がすでにわかっている場合は、次のように最適化できます。
// 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
}
});