$scopeNesneyi kirli kontrol ederek
Açısal array, $scopenesnelerdeki basit izleyicileri korur . Eğer herhangi birini incelerseniz $scopebunun bir arrayçağrı içeriyor olduğunu göreceksiniz $$watchers.
Her izleyici, objectdiğer şeylerin yanı sıra
- İzleyicinin izlediği bir ifade. Bu sadece bir
attributeisim 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
$scopekirli 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 $watchbir 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" />
$digestDö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 arrayve 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 $scopebir 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, $scopekirli
Bir izleyici tetiklenirse, uygulama bir şeyin değiştiğini bilir ve $scopekirli olarak işaretlenir.
İzleme işlevleri $scopebir üst öğedeki veya üst öğedeki diğer özellikleri değiştirebilir $scope. Bir $watcherişlev tetiklenmişse, diğer işlevlerimizin $scopehala 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 $scopeağ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 $digestkirli, biz tüm yürütmek $digesttekrar döngüsünü
$digestSindirim döngüsü temiz olana kadar (tüm $watchifadeler ö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, $scopenası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-repeatbü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ı, $scopeağ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-repeatbirçok öğeye sahip olduğunuzda özellikle önemlidir .
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>