Yönerge testinde $ apply vs $ Digest


98

Kapsamdaki belirli bir özniteliğin durumuna yanıt veren bir yönergem varsa ve bu özniteliği testimde değiştirmek ve doğru yanıt verdiğini doğrulamak istersem, bu değişikliği yapmanın en iyi yolu nedir?

Bu modellerin ikisini de gördüm:

scope.$apply(function() {
    scope.myAttribute = true;
});

ve

scope.myAttribute = true;
scope.$digest();

Aralarındaki fark nedir, hangisi daha iyi ve neden?

Yanıtlar:


206

scope.$digest()izleyicileri mevcut kapsamda ve tüm çocuklarında ateşleyecek. scope.$applygeçilen işlevi değerlendirecek ve çalıştıracaktır $rootScope.$digest().

Birincisi daha hızlıdır çünkü mevcut kapsam ve alt öğeleri için izleyicilerin değerlendirilmesi gerekir. İkincisi daha yavaştır, çünkü gözlemcileri $rootScopeve tüm alt kapsamları için değerlendirmesi gerekir .

Gözlemcilerden birinde bir hata oluştuğunda ve bunu kullandığınızda scope.$digest, bu $exceptionHandlerhizmet aracılığıyla ele alınmaz , bu nedenle istisnayı kendiniz halletmeniz gerekir. dahili olarak scope.$applybir try-catchblok kullanır ve tüm istisnaları $exceptionHandler.


1
Dürbün $digestçocukları da çağrılacak mı?
pilau

15
Bu yanıltıcı olabilir. $digestsadece mevcut kapsamdaki gözlemcileri değil, tüm çocuklarını da ateşliyor.
tasseKATT

@tasseKATT, sanırım yorumunuzun ne önerdiğini anladım.
activedecay

12

Dokümantasyonun kendisinden bahsedildiği gibi, yaptığınız her zaman $ özet döngüsü önceden biçimlendirilir $scope.$apply. Kapsamla ilgili geliştirici kılavuzuna göre

İfadeyi değerlendirdikten sonra, $ apply yöntemi bir $ özet gerçekleştirir. $ Digest aşamasında kapsam, tüm $ watch ifadelerini inceler ve bunları önceki değerle karşılaştırır.

Ve Scope API belgelerine göre

Genellikle $ Digest () öğesini doğrudan denetleyicilerde veya yönergelerde çağırmazsınız. Bunun yerine, bir $ apply () çağrısı (tipik olarak bir yönergenin içinden) bir $ Digest () 'yi zorlar.

Bu yüzden açıkça çağırmamalısınız $digest, $applyyöntem çağırmanız bir özet döngüsünü tetikleyecektir.


8
Bu doğru değildir çünkü özet, yalnızca mevcut kapsamın ve çocuklarının değerlendirilmesi gereken vakaların çoğu için yeterlidir. $ kapsam. $ uygulamanızın dahili olarak $ sindirme çağrısı yaptığı doğrudur, ancak bunun $ rootScope. $ Digest () 'i
çağıracağını
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.