$scope
Nesneyi kirli kontrol ederek
Açısal array
, $scope
nesnelerdeki basit izleyicileri korur . Eğer herhangi birini incelerseniz $scope
bunun bir array
çağrı içeriyor olduğunu göreceksiniz $$watchers
.
Her izleyici, object
diğer şeylerin yanı sıra
- İzleyicinin izlediği bir ifade. Bu sadece bir
attribute
isim veya daha karmaşık bir şey olabilir .
- İfadenin bilinen son değeri. Bu, ifadenin geçerli hesaplanan değerine göre kontrol edilebilir. Değerler farklıysa, gözlemci işlevi tetikler ve
$scope
kirli olarak işaretler .
- İzleyici kirliyse yürütülecek bir işlev.
İzleyiciler nasıl tanımlanır?
AngularJS'de bir izleyici tanımlamanın birçok farklı yolu vardır.
Açıkça can $watch
bir attribute
üstünde $scope
.
$scope.$watch('person.username', validateUnique);
{{}}
Şablonunuza bir enterpolasyon yerleştirebilirsiniz (geçerli olarak sizin için bir izleyici oluşturulur $scope
).
<p>username: {{person.username}}</p>
ng-model
İzleyiciyi sizin için tanımlamak gibi bir yönerge isteyebilirsiniz .
<input ng-model="person.username" />
$digest
Döngüsü son değerlerinde karşı gözlemcileri denetler
AngularJS ile normal kanallar (ng-model, ng-tekrar, vb.) Üzerinden etkileşime girdiğimizde, direktif tarafından bir özet döngüsü tetiklenir.
Bir sindirim döngüsü, tüm çocuklarının ve derinliğinin ilk geçişidir$scope
. Her biri için $scope
object
, onun üzerinde tekrarlıyoruz $$watchers
array
ve tüm ifadeleri değerlendiriyoruz. Yeni ifade değeri bilinen son değerden farklıysa, gözlemcinin işlevi çağrılır. Bu işlev, DOM'un bir bölümünü yeniden derleyebilir, üzerinde bir değeri yeniden hesaplayabilir , yapmanız gereken herhangi $scope
bir AJAX
request
şeyi tetikleyebilir .
Her kapsam geçer ve her saat ifadesi değerlendirilir ve son değerle karşılaştırılır.
Bir izleyici tetiklenirse, $scope
kirli
Bir izleyici tetiklenirse, uygulama bir şeyin değiştiğini bilir ve $scope
kirli olarak işaretlenir.
İzleme işlevleri $scope
bir üst öğedeki veya üst öğedeki diğer özellikleri değiştirebilir $scope
. Bir $watcher
işlev tetiklenmişse, diğer işlevlerimizin $scope
hala temiz olduğunu garanti edemeyiz ve bu nedenle tüm sindirim döngüsünü tekrar yürütürüz.
Bunun nedeni AngularJS'nin iki yönlü bağlanması olduğundan, veriler $scope
ağaca geri aktarılabilir . Daha $scope
önce sindirilmiş olan daha yüksek bir değeri değiştirebiliriz . Belki de bir değer değiştiririz $rootScope
.
Eğer $digest
kirli, biz tüm yürütmek $digest
tekrar döngüsünü
$digest
Sindirim döngüsü temiz olana kadar (tüm $watch
ifadeler önceki döngüdeki değerlerle aynı olana kadar ) veya özüm sınırına ulaşana kadar döngü boyunca sürekli döngü yaparız. Varsayılan olarak, bu sınır 10 olarak ayarlanmıştır.
Özet sınırına ulaşırsak AngularJS konsolda bir hata oluşturur:
10 $digest() iterations reached. Aborting!
Özet, makinede zor, ancak geliştiricide kolay
Gördüğünüz gibi, bir AngularJS uygulamasında her şey değiştiğinde AngularJS, $scope
nasıl yanıt verileceğini görmek için hiyerarşideki her izleyiciyi kontrol edecektir . Bir geliştirici için bu büyük bir üretkenlik nimetidir, şimdi neredeyse hiçbir kablolama kodu yazmanız gerekmediğinden, AngularJS sadece bir değerin değişip değişmediğini fark edecek ve uygulamanın geri kalanını değişiklikle tutarlı hale getirecektir.
Bu makinenin perspektifinden çılgınca verimsiz ve çok fazla izleyici yaratırsak uygulamamızı yavaşlatacaktır. Misko, uygulamanız eski tarayıcılarda yavaş hissetmeden önce yaklaşık 4000 gözlemciden alıntı yaptı.
Örneğin ng-repeat
büyük bir sınırın üzerindeyseniz bu sınıra ulaşmak kolaydır JSON
array
. İzleyici oluşturmadan bir şablonu derlemek için tek seferlik ciltleme gibi özellikleri kullanarak buna karşı hafifletebilirsiniz.
Çok fazla izleyici oluşturmaktan kaçınma
Kullanıcınız uygulamanızla her etkileşim kurduğunda, uygulamanızdaki her izleyici en az bir kez değerlendirilir. Bir AngularJS uygulamasını optimize etmenin büyük bir kısmı, $scope
ağacınızdaki izleyici sayısını azaltmaktır . Bunu yapmanın kolay bir yolu tek seferlik ciltlemedir .
Nadiren değişecek verileriniz varsa, :: sözdizimini kullanarak yalnızca bir kez bağlayabilirsiniz, şöyle:
<p>{{::person.username}}</p>
veya
<p ng-bind="::person.username"></p>
Bağlama yalnızca içerdiği şablon oluşturulduğunda ve içine veri yüklendiğinde tetiklenir $scope
.
Bu, ng-repeat
birçok öğeye sahip olduğunuzda özellikle önemlidir .
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>