2014-10-23 16 views
34

Do oglądania zmiennej zakresu obiektu, czy $scope.$watch z objectEquality jest ustawiona na true OR $scope.$watchCollection lepiej?

Dla zmiennej $scope obiektu (jak 15 atrybutów, niektóre zagnieżdżone 2 poziomy głębokości) aktualizowane z elementów wejściowych i ng-model w widoku, jak źle jest $scope.$watch z objectEquality zestaw do true? Czy jest to wielka rzecz, której należy unikać?

Czy lepszym rozwiązaniem jest ?

Poszukuję łatwych wygranych w celu poprawy wydajności mojej aplikacji AngularJS (nadal utknąłem w wersji 1.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 ... 

Odpowiedz

33

Funkcja $watchCollection() to sort-of połowy ziemi między dwa $watch() konfiguracjach powyżej. Jest bardziej dogłębna niż funkcja wanilla $ watch(); ale nie jest tak kosztowna jak funkcja głębokiej równości $watch(). Podobnie jak funkcja $watch(), $watchCollection() działa poprzez porównywanie fizycznych odwołań do obiektów; Jednak w przeciwieństwie do funkcji $watch(), $watchCollection() ma jeden poziom głębokości i wykonuje dodatkową, płytką kontrolę odniesienia elementów najwyższego poziomu w kolekcji.

see this explanation

2

$watchCollection jest zoptymalizowany do wektora arrays [] gdzie elementy można popchnąć

i $watch jest dobre dla asocjacyjnych obiektów {}

$watchCollection nie będzie obserwować zmiany głębokości, jest jak watch z objectEquality ustawionym na false.

Jeśli już wiesz do struktury głębokości można zoptymalizować tak:

// 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

$ oglądać() zostanie wyzwolony przez:

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

$ watchCollection() zostanie wywołane przez wszystko powyżej ORAZ:

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

$ zegarek (..., true) zostanie wyzwolony przez wszystko powyżej:

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

tylko jedna rzecz ...

$ oglądać() jest jedynym taki, który odpala, gdy tablica zostanie zastąpiona inną z tą samą dokładną zawartością.Na przykład:

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

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

$scope.myArray = newArray; 

Poniżej znajduje się link do przykładu JSFiddle że wykorzystuje wszystkie różne kombinacje oglądać i wyjścia wiadomości zalogować, aby wskazać, które zostały wywołane „zegarki”:

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

+0

bardzo dokładną !! – wbeange

+0

Nie jestem pewien, co masz na myśli przez '$ watchCollection (..., true)', ponieważ funkcja nie przyjmuje argumentu logicznego (np. ObjectEquality) takiego jak '$ watch'. – tamakisquare

+0

@tamakisquare Zrobiłem poprawkę i dodatkowe aktualizacje, aby były jaśniejsze. W tym aktualizacja JS Fiddle. –

Powiązane problemy