Soru Veri bağlama AngularJS'de nasıl çalışır?


Veri bağlama nasıl çalışır? AngularJS Çerçeve?

Teknik detayları bulamadım. siteleri. Veri, görünümden modele doğru yayıldığında nasıl çalıştığı daha açık veya anlaşılır bir şey. Fakat AngularJS, setter ve getters olmadan model özelliklerinde nasıl bir değişiklik yapar?

Var olduğunu buldum JavaScript gözlemcileri Bu işi yapabilir. Ancak bunlar desteklenmez Internet Explorer 6 ve Internet Explorer 7. AngularJS, örneğin aşağıdakileri değiştirdiğimi ve bu değişikliği bir bakış açısına yansıttığımı biliyor?

myobject.myproperty="new value";

1803
2018-03-13 10:16


Menşei


Açısal 1.0.0rc1'den beri ng-model-instant belirtmeniz gerektiğini unutmayın (docs-next.angularjs.org/api/...) senin moder inandırıcı güncellenmesi. Aksi takdirde bulanıklık olayında güncellenecektir. - Sotomajor
Marcello'nun bağlantısı görünüşte kırılmış, işte burada tekrar: github.com/mhevery/angular.js/blob/master/docs/content/guide/... - riffraff
@orian, bu link kötü. (varsayım) için güncelleştirildi aynı - docs.angularjs.org/guide/databinding - Kevin Meredith
Bu soruyu hala okuyanlar için, lütfen Angular 2.0'ın web bileşenleri ile çalışmak ve aşağıdaki cevaplarda bir çok sorunu ele almak için Angular 1.x'ten itibaren veri tabanına nasıl geçtiklerini büyük ölçüde değiştirdiğini unutmayın. - aug


Cevaplar:


AngularJS değeri hatırlar ve önceki bir değerle karşılaştırır. Bu temel kirli kontrol. Değerde bir değişiklik varsa, değişiklik olayını başlatır.

$apply() AngularJS dünyasından AngularJS dünyasına geçiş yaptığınızda aradığınız yöntem $digest(). Bir sindirim sadece eski kirli kontroldür. Tüm tarayıcılarda çalışır ve tamamen tahmin edilebilir.

Değişen dinleyicilere karşı kirli kontrolü (AngularJS) karşılaştırmak (KnockoutJS ve backbone.js): Kirli kontrol basit ve hatta verimsiz görünse de (bunu daha sonra ele alacağım), her zaman anlamsal olarak doğru olduğu ortaya çıkarken, değişimin dinleyicileri çok sayıda garip köşe vakasına sahip ve bağımlılık takibi gibi şeylere ihtiyaç duyuyor. daha semantik olarak doğru. KnockoutJS bağımlılık izleme, AngularJS'nin sahip olmadığı bir problem için akıllı bir özelliktir.

Değişim dinleyicileriyle ilgili sorunlar:

  • Sözdizimi oldukça zordur, çünkü tarayıcılar doğal olarak desteklemez. Evet, vekiller var, ancak her durumda anlamsal olarak doğru değiller ve tabii ki eski tarayıcılarda vekiller yok. En alt satır, kirli kontrolün yapmanı sağlıyor. POJOKnockoutJS ve Backbone.js, sınıflarından miras almanızı ve verilerinize erişimciler aracılığıyla erişmenizi sağlar.
  • Birleşmeyi değiştir. Bir dizi öğeniz olduğunu varsayalım. Eklemeye çalıştığınız gibi, bir diziye öğe eklemek istediğinizi varsayalım, her eklediğinizde, değişime neden olan olayları tetiklersiniz, bu da kullanıcı arayüzünü oluşturur. Bu performans için çok kötü. İstediğiniz şey UI'yi yalnızca bir kez güncellemek. Değişiklik olayları çok ince taneli.
  • Dinleyicileri bir sette hemen ateş edin, bu da bir sorundur, çünkü değişiklik dinleyicisi daha fazla değişiklik olayını tetikleyen verileri değiştirebilir. Bu kötü çünkü yığında bir anda birçok değişiklik olayı olabilir. Hangi nedenle olursa olsun senkronize edilmesi gereken iki diziniz olduğunu varsayalım. Yalnızca birine veya diğerine ekleyebilirsiniz, ancak her eklediğinizde, şimdi dünyanın tutarsız bir görünümü olan bir değişiklik olayı tetiklenir. Bu, kilitlemenin işlenmesiyle çok benzer bir sorundur; her bir geri dönüş özel olarak yürütme ve tamamlama işleminden sonra JavaScript'in önlenmesini sağlar. Değişim olayları bunu kırıyor çünkü ayarlayıcılar amaçlanmayan ve belirgin olmayan, çok fazla sonuçlara sahip olabiliyor, bu da iş parçacığı sorununu yeniden yaratıyor. Yapmak istediğiniz şey, dinleyicinin yürütülmesini geciktirmek ve bir kerede yalnızca bir dinleyicinin çalıştığını, dolayısıyla herhangi bir kodun veriyi değiştirmekte özgür olduğunu ve bu sırada başka bir kodun çalışmadığını bilmesini sağladığının ortaya çıkmasıdır. .

Performanstan ne haber?

Bu yüzden, yavaş kontrol ediyoruz, çünkü kirli kontrol etkisizdir. Burada sadece teorik argümanlara sahip olmak yerine gerçek sayılara bakmamız gerekiyor, ancak önce bazı kısıtlamalar tanımlayalım.

İnsanlar:

  • Yavaş - 50 ms'den daha hızlı olan herhangi bir şey insanlar için algılanamaz ve bu nedenle "anlık" olarak kabul edilebilir.

  • Sınırlı - İnsanlara tek bir sayfada 2000'den fazla bilgi gösteremezsiniz. Bundan daha fazla bir şey gerçekten kötü UI'dir ve insanlar bunu zaten işleyemez.

Yani asıl soru şudur: 50 ms'de bir tarayıcıda kaç tane karşılaştırma yapabilirsiniz? Bu, birçok faktörün devreye girmesi için zor bir sorudur, ancak burada bir test vakası: http://jsperf.com/angularjs-digest/6 hangi 10,000 gözlemci oluşturur. Modern bir tarayıcıda bu sadece 6 ms altında alır. üzerinde Internet Explorer 8 yaklaşık 40 ms sürer. Gördüğünüz gibi, bu günlerde yavaş tarayıcılarda bile bir sorun değil. Bir uyarı var: Karşılaştırmalar zaman sınırına uymak için basit olması gerekiyor ... Ne yazık ki AngularJS yavaş bir karşılaştırma eklemek için çok kolay, bu yüzden ne olduğunu bilmiyorsanız yavaş uygulamalar oluşturmak kolaydır yapıyorlar. Ancak, hangisinin yavaş karşılaştırmalar olduğunu gösteren bir enstrümantasyon modülü sağlayarak bir yanıt vermeyi umuyoruz.

Video oyunları ve GPU'ların, özellikle tutarlı olduğu için kirli kontrol yaklaşımını kullandıkları ortaya çıkıyor. Monitör yenileme hızını (genellikle 50-60 Hz ya da her 16.6-20 ms) geçtikçe, herhangi bir performans bir israftır, bu yüzden FPS daha yüksek olmaktan çok daha fazla şey çizmekten daha iyidir.


2660
2018-03-13 23:47



@Mark - evet, KO'da, üzerinde değişiklik yapmadan önce son değişiklik olayından sonra 500 milisaniye beklemek için .extend ({throttle: 500}) ekleyin. - Daniel Earwicker
Bu cevabın tamamı, "50 fps aldıkları sürece, bunun üzerindeki herhangi bir performans bir çöptür, çünkü insan gözü bunu takdir edemez, bu yüzden daha fazla şey çekmekten daha iyi olursunuz. Bu ifade uygulamanıza bağlı olarak tamamen yanlıştır. Göz, 50 fps'yi aşan bir değere sahip olabilir ve VR şovu ile ilgili çeşitli problemler (John Carmack veya Michael Abrash, özellikle de sonuncusu GDC 2013 VR konuşmasından en son haberleri okuyun), 50 fps aslında çok yavaştır. Bunun dışında cevabınız harika. Sadece yanlış bilginin yayılmasını istemiyorum. - Nate Bundy
Sadece merak, app Twitter veya yorum konu / forum gibi ise ve Angular dayalı sonsuz kaydırma uygulamak, "2000 adet bilgi" "limit" içine koşabilir, merak ediyorum. Tek bir yorum kolayca yazarın adı, profil img, içerik, datetime ve vb için çeşitli değişkenlere sahip olabilir. Ayrıca, tüm yorumlar / mesajlar saklamak için bir dev dizi var, her kirli kontrol bu dizi tarama gerektirir Ben haklıyım Bu, tarayıcıyı kötü bir kullanıcı deneyimi olan zamanlarda biraz hafifletir. Bu durumda makul performans sağlamak için ne yapmamızı öneriyorsunuz? - Lucas
İfadenin tersine "Kirli kontrol, nakavt olmayan bir problem için akıllıca bir özelliktir" şeklinde açıklanabilir. ES6 gözlenebilirleri kullanıyor ve açısal kirlilik kontrolünden kurtuluyor. Gerçek dünya bu cevabı yakaladı ve yanlış olduğunu gösterdi. - conical
"50 ms'den daha hızlı olan herhangi bir şey insanlara algılanamaz" doğru değildir. Testlerimizde müşterilerimizin 50ms güncelleme gecikmesi (20fps) ve 16.6ms güncelleme gecikmesi (60fps) arasında kolayca ayırt edebildiğini tespit ettik. Eski hızda çalışan sahneler, insanların çerçeveyi bilinçli olarak kaydetmediği durumlarda bile, genel olarak "nasıl hissettiğini" derecelendiren notları sürekli olarak kötüleştiriyor. - Crashworks


Misko zaten veri bağlarının nasıl çalıştığına dair mükemmel bir açıklama yaptı, ancak veri bağlama ile performans konusundaki görüşümü eklemek istiyorum.

Misko'nun belirttiği gibi, 2000 civarında bağlanma, sorunları görmeye başladığınız yerdir, ancak yine de bir sayfada 2000'den fazla bilgi olmamalıdır. Bu doğru olabilir, ancak her veri bağlama, kullanıcı tarafından görülebilir değildir. İki yönlü ciltleme ile herhangi bir tür widget veya veri ızgarası oluşturmaya başladığınızda kolayca kötü bir ux olmadan 2000 bağlamaları vurdu.

Örneğin, mevcut seçenekleri filtrelemek için metin yazabileceğiniz bir combobox düşünün. Bu tür kontrol ~ 150 ürüne sahip olabilir ve yine de oldukça kullanışlı olabilir. Ekstra özelliği varsa (örneğin o anda seçili seçenekte belirli bir sınıf), seçenek başına 3-5 ciltleme almaya başlarsınız. Bu widget'lardan üçünü bir sayfaya (ör. Bir ülke seçmek için, diğeri bir ülkeyi seçmek için, diğeri bir oteli seçmek için) koyun ve zaten 1000 ile 2000 bağlama arasında bir yerdesiniz.

Veya kurumsal bir web uygulamasında bir veri kılavuzunu düşünün. Sayfa başına 50 satır mantıksız değildir, her biri 10-20 sütun içerebilir. Bunu ng-yinelemeleri ile yapılandırırsanız ve / veya bazı bağlamalar kullanan bazı hücrelerde bilgi varsa, bu kılavuz ile yalnızca 2000 bağına yaklaşıyor olabilirsiniz.

Bunu bir olmak için buluyorum Kocaman AngularJS ile çalışırken sorunum ve şu ana kadar bulabildiğim tek çözüm, ngOnce kullanarak, deregistering gözlemcileri ve benzer hileleri kullanarak iki yönlü bağlama kullanmadan widget oluşturmak veya DOM'ı jQuery ile oluşturan direktifleri oluşturmaktır. DOM manipülasyonu. Bu yenilgileri ilk bakışta Angular kullanmanın amacını hissediyorum.

Bunun üstesinden gelmek için başka yollarla ilgili önerileri duymak isterdim, ama sonra kendi sorumu yazmalıyım. Bunu bir yorumun içine koymak istedim, ama bunun için çok uzun bir yol olduğu ortaya çıktı ...

TL; DR 
Veri bağlama karmaşık sayfalarda performans sorunlarına neden olabilir.


308
2017-08-22 13:28



Evet, buna ikinciyim. Uygulamamızın birincil sorumluluğu farklı varlıklar arasındaki bağlantıları görüntülemektir. Belirli bir sayfada 10 bölüm bulunabilir. Her bölümün bir tablosu vardır. Her tablonun 2-5 typeahead filtresi vardır. Her tablonun her biri 10 satırlı 2-5 sütun vardır. Çok hızlı bir şekilde mükemmel konulara giriyoruz ve "benzer numaralar" seçenekleriyle devam ediyoruz. - Scott Silvi
Angular sadece veri bağlama ile ilgili değildir ve bazı uygulamalar, diğerlerinin atıf yaptığı nedenlerden dolayı bu özelliği kullanmak istemeyebilir söylemek adil mi? DI ve modülerlik yaklaşımının kendisinin çok fazla olduğunu düşünüyorum; Büyüleyici otomatik bağlama özelliğine sahip olmak güzeldir ancak mevcut her uygulamada performansın artması söz konusudur. Açısallığın yolu, CRUD web uygulamalarının çoğunluğu için tartışmasız bir şekilde üstündür ve insanlar uçağa binmeye çalışarak sadece bir duvara çarpmaktadır. Desteklenen olay dinlemenin alternatif bir yöntemine sahip olmak güzel olurdu, ancak belki de tek bir çerçeve için temelde çok karmaşık olan bu mu? - Jason Boyd
Angular şimdi tek bir yol var ve bu problemi çözmeye yardımcı olmak için bir kere bağlanabiliyor. Üstelik şimdi tekrarlayıcı kaynağınız için, içeriğin tamamını yeniden oluşturmadan listeyi değiştirebilmenizi sağlayan dizinlere sahiptir. - Mithon
@MW. Dürüst olmak gerekirse, bir zamanlar çekirdeğin içinde olduğunu sandım. Ama öyle değil gibi görünüyor. Bu sadece kendi direktiflerinizi yazarken yapabileceğiniz, temelde onları izlemeye gerek duymadan bir şeyler yapabildiğiniz bir şey. Ancak bunun için bir ux mod var: github.com/pasvaz/bindonce - Mithon
Bunu okuyan herkes için gelecekten bir not: Şimdi bir kez bağlama Angular v1.3'te çekirdek bir özellik, daha fazla bilgi burada: docs.angularjs.org/guide/expression - Nobita


Kirli kontrol ederek $scope nesne

Açısal basit bir korur array içinde gözlemciler $scope nesneler. Eğer herhangi bir kontrol ederseniz $scope bir tane içerdiğini göreceksiniz array denilen $$watchers.

Her izleyici bir object diğer şeylerin arasında yer alıyor

  1. İzleyicinin izlediği bir ifade. Bu sadece bir attribute ad veya daha karmaşık bir şey.
  2. İfadenin bilinen son bir değeri. Bu, ifadenin mevcut hesaplanan değerine göre kontrol edilebilir. Değerler farklıysa, gözlemci fonksiyonu tetikler ve $scope kirli gibi.
  3. İzleyici kirli ise idam edilecek bir işlev.

İzleyiciler nasıl tanımlanır?

AngularJS'de bir gözlemciyi tanımlamanın birçok farklı yolu vardır.

  • Açıkça yapabilirsiniz $watch bir attribute üzerinde $scope.

    $scope.$watch('person.username', validateUnique);
    
  • Yerleştirebilirsin {{}} Şablonunuzda enterpolasyon (şu an sizin için bir gözlemci oluşturulacaktır) $scope).

    <p>username: {{person.username}}</p>
    
  • Gibi bir yönerge isteyebilirsiniz ng-model izleyiciyi sizin için tanımlamak.

    <input ng-model="person.username" />
    

$digest döngüsü tüm gözlemcileri son değerlerine göre kontrol eder

AngularJS ile normal kanallar arasında etkileşimde bulunduğumuzda (ng-model, ng-repeat, vb.) Direktif tarafından bir sindirim döngüsü tetiklenecektir.

Bir sindirim döngüsü derinlik-ilk geçiş $scope ve tüm çocukları. Her biri için $scope  object, onun üzerinde yineliyoruz $$watchers  array ve tüm ifadeleri değerlendirir. Yeni ifade değeri bilinen son değerden farklıysa, izleyicinin işlevi çağrılır. Bu işlev DOM'ın bir kısmını yeniden derleyebilir, bir değeri yeniden hesaplayabilir $scope, tetikle AJAX  requestYapman gereken bir şey var.

Her kapsam geçilir ve her saat ifadesi son değere göre değerlendirilir ve kontrol edilir.

Bir gözlemci tetiklenirse, $scope kirli

Bir gözlemci tetiklenirse, uygulama bir şeyin değiştiğini bilir ve $scope kirli olarak işaretlenmiştir.

Gözcü işlevleri diğer özellikleri değiştirebilir $scope veya bir ebeveyn üzerinde $scope. Eğer biri $watcher işlev tetiklendi, diğer tarafımızın garantisini veremeyiz $scopes hala temiz ve böylece tüm sindirim döngüsünü tekrar çalıştırıyoruz.

Bunun nedeni, AngularJS'nin iki yönlü bir bağlamaya sahip olmasıdır, bu nedenle veriler geri alınabilir $scopeağacı. Bir değeri daha yüksekte değiştirebiliriz $scope zaten sindirilmiş. Belki de bir değeri değiştiriyoruz $rootScope.

Eğer $digest kirli, biz tüm yürütmek $digest tekrar döngü

Sürekli olarak $digest sindirim döngüsü temiz oluncaya kadar devir $watch ifadeler, önceki döngüde olduğu gibi aynı değere sahiptir veya sindirim sınırına ulaşırız. Varsayılan olarak, bu sınır 10 olarak ayarlanmıştır.

Sindirme sınırına ulaşırsak AngularJS, konsolda bir hata oluşturur:

10 $digest() iterations reached. Aborting!

Sindirim makinede zor ama geliştirici üzerinde kolay

Gördüğünüz gibi, AngularJS uygulamasında her şey değiştiğinde, AngularJS her bir izleyiciyi $scope nasıl tepki vereceğini görmek için hiyerarşi. Bir geliştirici için bu, büyük bir üretkenlik nimetidir, şimdi neredeyse hiç kablolama kodu yazmanız gerekmediğinden, AngularJS bir değerin değişip değişmediğini fark edecek ve uygulamanın geri kalanını değişiklikle tutarlı hale getirecektir.

Makinenin bakış açısına göre, bu durum çok verimsizdir ve çok sayıda izleyici oluşturduğumuzda uygulamanızı yavaşlatır. Misko, uygulamanızın eski tarayıcılarda yavaşlayabilmesi için yaklaşık 4000 izleyicinin bir rakamını aktardı.

Bu sınır eğer ulaşmak için kolay ng-repeat büyük üzerinde JSON  array Örneğin. Bir çekiciyi oluşturmadan bir şablonu derlemek için bir kerelik ciltleme gibi özellikleri kullanarak bunu azaltabilirsiniz.

Çok fazla gözlemci oluşturmaktan nasıl kaçınabilirsiniz?

Kullanıcınız uygulamanızla her etkileşimde bulunduğunda, uygulamanızdaki her izleyici en az bir kez değerlendirilecektir. AngularJS uygulamasını optimize etmenin büyük bir kısmı, $scope ağacı. Bunu yapmanın kolay bir yolu şudur: bir kez bağlama.

Nadiren değişecek olan verileriniz varsa, sadece bir kez :: sözdizimini kullanarak bağlayabilirsiniz:

<p>{{::person.username}}</p>

veya

<p ng-bind="::person.username"></p>

Bağlama, yalnızca içeren şablon oluşturulduğunda ve veriler yüklendiğinde tetiklenir. $scope.

Bu özellikle bir ng-repeat birçok öğe ile.

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>

142
2018-06-02 12:31



Söz konusu cevabın en üstte olması gerektiğine katılmıyorum; Bir şeyi bilmek ve belirli bir soru için uygun / ayrıntılı cevap yazmak arasında bir fark vardır. Övgü almanın daha iyi yolları var. Her neyse .. - user2864740
Böyle doğru olduğundan şüphe etmiyorum, ama soruları cevaplar ve cevapları cevaplar :) - user2864740
Pis-kontrolün nasıl davrandığını ve gerçekte neyi değerlendirdiğini anlatan güzel cevap, Misko'nun cevabında bir şey açık değildi. - bitstrider
Mükemmel ve detaylı cevap. @superluminary, bu tür bir cevap için teşekkürler. Dahası, bu cevabı okuduktan sonra, idempotent olmayan ifadeyi izlenen bir ifade olarak eklemememiz gereken noktaya geliyorum. - Mangu Singh Rajpurohit
Bu en iyi cevap olmalı - Alexandre Bourlier


Bu benim temel anlayışım. Bu yanlış olabilir!

  1. Bir fonksiyon geçerek öğeler izlenir ( izledi) $watch yöntem.
  2. İzlenen öğelerdeki değişiklikler bir kod bloğunda yapılmalıdır tarafından sarılmış $apply yöntem.
  3. Sonunda $apply  $digest hangi yöntem gider denir her bir saat boyunca ve bu yana değişip değişmediklerini görmek için son kez $digest koştu.
  4. Herhangi bir değişiklik bulunursa, tüm değişiklikler stabil olana kadar özet tekrar başlatılır.

Normal geliştirmede, HTML'deki veri bağlama sözdizimi, AngularJS derleyicisinin sizin için saatler oluşturmasını ve denetleyici yöntemlerinin içinde çalışmasını sağlar. $apply zaten. Yani uygulama geliştiricisine tüm şeffaftır.


77
2018-03-13 21:01



uygulama yöntemi ne zaman tetiklenir? - numan salati
@EliseuMonar Özet döngüsü, bazı olayların bir sonucu olarak veya $ apply () öğesini çağırdığında çalışır; bu, bir zamanlayıcıya bağlı olarak periyodik olarak adlandırılmaz. görmek AngularJS'nin $ watch fonksiyonu nasıl çalışır? ve Bağlanma ve sindirme AngularJS'de nasıl çalışır? - remi
@remi, AngularJS'nin son sürümü hakkında endişe duymuyorum. Zaten proxy veya Object.observe kullanıyorlar mı? Değilse, hala model kontrollerinin değişip değişmediğini görmek için zamanlanmış bir döngü oluşturan kirli kontrol çağındalar. - Eliseu Monar dos Santos
Sindirmenin en fazla on kez çalışacağını okudum sitepoint.com/understanding-angulars-apply-digest - user137717


Bunu bir süredir merak ettim. Setters olmadan nasıl AngularJS değişiklik bildirimi $scope nesne? Onları kirletiyor mu?

Aslında ne yapıyor: Bu modeli değiştirdiğiniz herhangi bir "normal" yer zaten bağırsaklarından çağrıldı AngularJS, bu yüzden otomatik olarak çağırır $apply Kodunuz çalıştıktan sonra sizin için. Kontrol cihazınızın bağlı olduğu bir yöntem olduğunu varsayalım. ng-click bazı elemanlarda. Çünkü AngularJS Bu yöntemin sizin için bir araya gelmesini sağlar, bir $apply uygun yerde. Aynı şekilde, görüşlerde doğru görünen ifadeler için, AngularJS yani yapar $apply.

Dokümanlar aramak zorunda kaldıklarında $apply kod için el ile dışında AngularJSkoşarken, kaynaklanmayan koddan bahsediyor AngularJS çağrı yığınının kendisi.


57
2017-09-03 17:45





Resimlerle Açıklamak:

Veri Bağlama bir haritalamaya ihtiyaç duyar

Kapsamdaki referans, şablondaki tam referans değildir. İki nesneyi veriye bağladığınızda, ilkini dinleyen ve diğerini değiştiren üçüncü birine gereksiniminiz vardır.

enter image description here

Burada, <input>sen dokun Veri REF3. Ve klasik veri bağlama mecanizması değişecek Veri REF4. Öyleyse diğer nasıl {{data}} ifadeler hareket edecek?

Etkinlikler $ digest () yol açar

enter image description here

Açısal korur oldValue ve newValue her bağın Ve her şeyden sonra Açısal olay, ünlü $digest() döngü, bir şeyin değişip değişmediğini görmek için İzleme Listesini kontrol edecektir. Bunlar Açısal olaylar Hangi ng-click, ng-change, $http tamamlandı ... $digest() herhangi bir uzun sürece döngü olacak oldValue farklıdır newValue.

Önceki resimde, data-ref1 ve data-ref2'nin değiştiğini görecektir.

Sonuçlar

Yumurta ve Tavuk gibi biraz. Kimin başladığını asla bilemezsiniz, ama umarim ki çoğu zaman beklendiği gibi çalışır.

Diğer bir nokta, bellek ve CPU üzerindeki basit bir bağlamanın derinliğini kolayca anlayabilmenizdir. Umarım masaüstleri bunu halledecek kadar şişmandır. Cep telefonları o kadar güçlü değil.


29
2018-05-20 13:33





Açıkçası, periyodik kontrol yoktur. Scope Eklenen Nesnelerde herhangi bir değişiklik olup olmadığı. Kapsama eklenen tüm nesneler izlenmez. Kapsam prototip olarak korur $$ gözlemcileri . Scope sadece bunun üzerinden yinelenir $$watchers ne zaman $digest denir.

Açısal, her biri için $$ gözlemciye bir gözlemci ekler

  1. {{expression}} - Şablonlarınızda (ve bir ifadenin bulunduğu herhangi bir yerde) veya ng modelini tanımladığımızda.
  2. $ scope. $ watch (‘expression / function’) - JavaScript’inizde, izlemek için açısal olarak bir kapsam nesnesi ekleyebiliriz.

$ izle işlev üç parametre alır:

  1. Birincisi, sadece nesneyi döndüren veya sadece bir ifade ekleyebilen bir gözlemci işlevidir.

  2. İkincisi, nesnede bir değişiklik olduğunda çağrılacak bir dinleyici işlevidir. DOM değişiklikleri gibi tüm şeyler bu işlevde uygulanacaktır.

  3. Üçüncüsü, bir boole olan isteğe bağlı bir parametredir. Eğer onun gerçek, açısal derin nesneyi izlerse ve eğer onun yanlış Köşesi sadece nesne üzerinde bir referans izler.     $ Watch'ın Kaba Uygulaması buna benziyor

Scope.prototype.$watch = function(watchFn, listenerFn) {
   var watcher = {
       watchFn: watchFn,
       listenerFn: listenerFn || function() { },
       last: initWatchVal  // initWatchVal is typically undefined
   };
   this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

Açısal olarak Digest Cycle adlı ilginç bir şey var. $ Digest döngüsü $ kapsamına yapılan bir çağrı sonucunda başlar. $ Digest (). Tıklatma yönergesini kullanarak bir işleyici işlevinde bir kapsam modelini değiştirdiğinizi varsayalım. Bu durumda AngularJS, $ digest () öğelerini arayarak $ digest döngüsünü otomatik olarak tetikler. Tıklamanıza ek olarak, modelleri değiştirmenize izin veren diğer yerleşik yönergeler / hizmetler de vardır (örn. Ng-model, $ timeout, vb.). ve otomatik olarak bir $ digest döngüsü tetikler. $ Digest'in kaba uygulaması böyle görünüyor.

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce();
      } while (dirty);
}
Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

JavaScript’i kullanırsak setTimeout () Bir kapsam modelini güncellemek için fonksiyon, Angular ne değişebileceğini bilmenin bir yolu yoktur. Bu durumda, $ digest döngüsünü tetikleyen $ apply () öğesini elle çağırmak bizim sorumluluğumuzdur. Benzer şekilde, bir DOM olay dinleyicisi oluşturan ve işleyici işlevinin bazı modellerini değiştiren bir yönergeye sahipseniz, değişikliklerin yürürlüğe girmesini sağlamak için $ apply () öğesini çağırmanız gerekir. $ Apply'ın büyük fikri, Angular'ın farkında olmayan bazı kodları yürütebileceğimiz, bu kodun hala kapsamdaki şeyleri değiştirebileceğidir. Bu kodu $ uygulamasında değiştirirsek, $ digest () öğesini çağırırız. $ Apply () öğesinin kaba uygulanması.

Scope.prototype.$apply = function(expr) {
       try {
         return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};

19
2018-05-22 18:18





AngularJS, üç güçlü işlevden yararlanarak veri bağlama mekanizmasını kullanır: $ Izle (),$ Özet ()ve ) (Uygulamak, $. Çoğu zaman AngularJS, $ scope. $ Watch () ve $ scope. $ Digest () öğesini çağırır. Bazı durumlarda yeni değerleri güncellemek için bu işlevleri manuel olarak çağırmanız gerekebilir.

$ Izle () : -

Bu işlev, $ kapsamındaki bir değişkendeki değişiklikleri gözlemlemek için kullanılır.   Üç parametre kabul eder: ifade, dinleyici ve eşitlik nesnesi,   dinleyici ve eşitlik nesnesi isteğe bağlı parametrelerdir.

$ Özet () -

Bu işlev $ kapsam nesnesindeki tüm saatler boyunca yinelenir,   ve onun $ kapsam nesneleri
     (eğer varsa). $ Digest () yinelendiğinde   saatler üzerinde, ifadenin değerinin olup olmadığını kontrol eder   değişti. Değer değiştiyse, AngularJS dinleyiciyi   yeni değer ve eski değer. $ Digest () işlevi çağrılır   AngularJS gerekli olduğunu düşündüğünde. Örneğin, bir düğmeden sonra   AJAX aramasından sonra veya tıklayın. AngularJS'nin olduğu bazı durumlar olabilir.   sizin için $ digest () işlevini çağırmaz. Bu durumda   Kendin de.

) (Uygulamak, $ -

Açısal otomatik olarak sadece bu model değişikliklerini günceller   AngularJS bağlamında. Dışında herhangi bir modelde değişiklik yaptığınızda   Açısal bağlam (tarayıcı DOM olayları, setTimeout, XHR veya üçüncü gibi)   parti kütüphaneleri), daha sonra değişikliklerin açısal değerini bildirmeniz gerekir.   el ile $ apply () çağırıyor. $ Apply () işlevi çağrısı bittiğinde   AngularJS, dahili olarak $ digest () çağırır, böylece tüm veri bağlamaları   güncellenmiş.


12
2018-05-16 15:05



bu bana yardımcı oldu - Jayani Sumudini