2014-10-23 2 views
34

Для наблюдения за областью видимости объекта является $scope.$watch с objectEquality установлен в true ИЛИ $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 ... 

ответ

33

$watchCollection() функция является своим родом-середины земли между два $watch() конфигурациями выше. Это более подробно, чем функция вахты $ 0 ( ); но это не так дорого, как функция с глубоким равенством $watch(). Подобно функции $watch(), $watchCollection() работает путем сравнения ссылок на физические объекты; Однако, в отличие от функции $watch(), $watchCollection() отправляет одноуровневый уровень и выполняет дополнительную, мелкую контрольную проверку элементов верхнего уровня в коллекции.

see this explanation

2

$watchCollection оптимизирован для вектора arrays [] где элементы могут быть толкнуть

и $watch хорошо для ассоциативных массивов объектов {}

$watchCollection не будет следить за изменением глубины, это как часы с объектомEquality установлено на 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 
    } 
    }); 
153

$ смотреть() будет вызван:

$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 

$ часы (..., правда) будет вызвано все выше и:

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

ПРОСТО ЕЩЕ ОДИН ВЕЩЬ ...

$ смотреть() является единственным тот, который срабатывает, когда массив заменяется другим с тем же самым точным контентом.Например:

$scope.myArray = ["Apples", "Bananas", "Orange" ]; 

var newArray = []; 
newArray.push("Apples"); 
newArray.push("Bananas"); 
newArray.push("Orange"); 

$scope.myArray = newArray; 

Ниже приводится ссылка на пример, который использует JSFiddle все различные комбинации часы и выводит лог-сообщения, чтобы указать, какие «часы» были вызваны:

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

+0

очень тщательно !! – wbeange

+0

Не уверен, что вы подразумеваете под '$ watchCollection (..., true)', поскольку функция не принимает логический аргумент (например, objectEquality), как '$ watch'. – tamakisquare

+0

@tamakisquare Я сделал исправление и дополнительные обновления, чтобы сделать его более ясным. Включая обновление скрипта JS. –

Смежные вопросы