Brudne sprawdzanie $scope
obiektu
Angular utrzymuje prostą array
obserwację $scope
obiektów. Jeśli sprawdzisz jakiś $scope
, okaże się, że zawiera on array
wywołanie $$watchers
.
Każdy obserwator object
zawiera między innymi
- Wyrażenie monitorowane przez obserwatora. To może być tylko
attribute
nazwa lub coś bardziej skomplikowanego.
- Ostatnia znana wartość wyrażenia. Można to porównać z bieżącą obliczoną wartością wyrażenia. Jeśli wartości się różnią, obserwator uruchomi funkcję i oznaczy
$scope
jako brudny.
- Funkcja, która zostanie wykonana, jeśli obserwator jest brudny.
Jak definiowani są obserwatorzy
Istnieje wiele różnych sposobów definiowania obserwatora w AngularJS.
Można wyraźnie ty na .$watch
attribute
$scope
$scope.$watch('person.username', validateUnique);
Możesz umieścić {{}}
interpolację w swoim szablonie (dla bieżącego zostanie utworzony obserwator $scope
).
<p>username: {{person.username}}</p>
Możesz poprosić o dyrektywę, taką jak ng-model
zdefiniowanie obserwatora dla ciebie.
<input ng-model="person.username" />
$digest
Cykl sprawdza wszystkie obserwatorów przed ich ostatniej wartości
Kiedy wchodzimy w interakcję z AngularJS poprzez normalne kanały (model ng, powtórzenie ng itp.), Dyrektywa uruchomi cykl podsumowania.
Cykl trawienia to pierwsze przejście w głąb $scope
i wszystkich jego dzieci . Dla każdego z nich $scope
object
iterujemy $$watchers
array
i oceniamy wszystkie wyrażenia. Jeśli nowa wartość wyrażenia różni się od ostatniej znanej wartości, wywoływana jest funkcja obserwatora. Ta funkcja może ponownie skompilować część DOM, ponownie obliczyć wartość $scope
, wyzwolić AJAX
request
dowolne potrzebne zadanie.
Każdy zakres jest przeglądany, a każde wyrażenie obserwowane jest oceniane i sprawdzane względem ostatniej wartości.
Jeśli obserwator zostanie wyzwolony, $scope
jest brudny
Jeśli obserwator zostanie wyzwolony, aplikacja wie, że coś się zmieniło i $scope
jest oznaczony jako brudny.
Funkcje obserwatora mogą zmieniać inne atrybuty na $scope
lub na rodzicu $scope
. Jeśli jedna $watcher
funkcja została uruchomiona, nie możemy zagwarantować, że nasze pozostałe $scope
są nadal czyste, dlatego ponownie wykonujemy cały cykl podsumowania.
Wynika to z faktu, że AngularJS ma dwukierunkowe wiązanie, dzięki czemu dane mogą być przekazywane z powrotem do $scope
drzewa. Możemy zmienić wartość wyższą, $scope
która została już przetworzona. Być może zmienimy wartość na $rootScope
.
Jeśli $digest
jest brudny, $digest
ponownie wykonujemy cały cykl
Ciągle zapętlamy $digest
cykl, aż albo cykl podsumowania nie stanie się czysty (wszystkie $watch
wyrażenia mają taką samą wartość jak w poprzednim cyklu), lub osiągniemy limit podsumowania. Domyślnie limit ten wynosi 10.
Jeśli osiągniemy limit skrótu, AngularJS zgłosi błąd w konsoli:
10 $digest() iterations reached. Aborting!
Podsumowanie jest trudne na komputerze, ale łatwe dla programisty
Jak widać, za każdym razem, gdy coś zmienia się w aplikacji AngularJS, AngularJS sprawdzi każdego obserwatora w $scope
hierarchii, aby zobaczyć, jak zareagować. Dla programisty jest to ogromny dar wydajności, ponieważ teraz nie musisz pisać prawie żadnego kodu okablowania, AngularJS po prostu zauważy, czy wartość się zmieniła, i sprawi, że reszta aplikacji będzie zgodna ze zmianą.
Z punktu widzenia maszyny jest to jednak bardzo nieefektywne i spowolni naszą aplikację, jeśli utworzymy zbyt wielu obserwatorów. Misko podało liczbę około 4000 obserwatorów, zanim Twoja aplikacja będzie działać wolniej w starszych przeglądarkach.
Ten limit jest łatwo osiągalny, jeśli na przykład ng-repeat
przekraczasz dużą wartość JSON
array
. Można temu zaradzić, korzystając z takich funkcji, jak jednorazowe wiązanie w celu skompilowania szablonu bez tworzenia obserwatorów.
Jak uniknąć tworzenia zbyt wielu obserwatorów
Za każdym razem, gdy użytkownik wchodzi w interakcję z aplikacją, każdy obserwator w Twojej aplikacji zostanie oceniony co najmniej raz. Dużą częścią optymalizacji aplikacji AngularJS jest zmniejszenie liczby obserwatorów w twoim $scope
drzewie. Jednym łatwym sposobem na to jest wiązanie jednorazowe .
Jeśli masz dane, które rzadko się zmieniają, możesz je powiązać tylko raz, używając składni ::, tak jak:
<p>{{::person.username}}</p>
lub
<p ng-bind="::person.username"></p>
Powiązanie zostanie uruchomione tylko wtedy, gdy szablon zawierający zostanie wyrenderowany i dane zostaną załadowane $scope
.
Jest to szczególnie ważne, gdy masz ng-repeat
wiele przedmiotów.
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>