Açısal JS: Yönerge kapsamı olan bir denetleyicimiz olduğunda, direktifin bağlantı işlevine ne gerek vardır?


201

Kapsam ve şablon üzerinde bazı işlemler yapmam gerekiyor. Görünüşe göre bunu linkfonksiyonda veya controllerfonksiyonda yapabilirim (çünkü her ikisinin de kapsama erişimi vardır).

linkDenetleyiciyi değil, işlevi kullanmak zorunda kaldığımda ne zaman olur ?

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}

Ayrıca, bunun linkaçısal olmayan dünya olduğunu anlıyorum . Yani, kullanabilir $watch, $digestve $apply.

linkZaten denetleyicimiz olduğunda , işlevin önemi nedir ?


9
Eğer ne demek istiyorsunuz " Ayrıca, ben bağlantı. Yani, kullanabilirsiniz olmayan açısal dünya anlıyorum $watch, $digestve $apply. "?
musically_ut

2
İçinde linkaçısal bir sihir görmüyoruz. yani 2 yollu ciltleme, vb. Sadece açısal api kullanmak için kullanılabilir.
Yugal Jindle

Yanıtlar:


300

Ve fonksiyonları ile ilk mücadelemden linkve controlleronlar hakkında çok şey okuduktan sonra , şimdi cevabım olduğunu düşünüyorum.

İlk sağlar anlama ,

Açısal direktifler kısaca nasıl çalışır:

  • Bir şablonla başlıyoruz (dize olarak veya bir dizeye yüklenmiş)

    var templateString = '<div my-directive>{{5 + 10}}</div>';

  • Şimdi, bu açısal bir elemantemplateString olarak sarılmış

    var el = angular.element(templateString);

  • İle el, şimdi bağlantı fonksiyonu $compilegeri almak için ile derlemek .

    var l = $compile(el)

    İşte olan,

    • $compile şablonun tamamında yürür ve tanıdığı tüm yönergeleri toplar.
    • Bulunan tüm direktifler özyinelemeli olarak derlenir ve linkişlevleri toplanır.
    • Ardından, tüm linkişlevler yeni bir linkişleve sarılır ve olarak döndürülür l.
  • Son olarak, bu ve bunlara karşılık gelen elemanlarla sarılmış bağlantı fonksiyonlarını daha da yürüten scopebu l(link) fonksiyonuna fonksiyon sağlıyoruz scope.

    l(scope)

  • Bu template, 'a yeni bir düğüm olarak ekler ve saatlerini DOMDOM'daki şablonla paylaşılan kapsamacontroller ekler .

resim açıklamasını buraya girin

Karşılaştırma compile vs link vs controller :

  • Her direktif sadece bir kez derlenir ve link fonksiyonu yeniden kullanım için korunur. Bu nedenle, bir direktifin tüm örnekleri için geçerli bir şey varsa, direktifin compileişlevi içinde gerçekleştirilmelidir .

  • Şimdi, derleme sonra elimizdeki linktakarken gerçekleştirdiği işlevi şablonu için DOM . Bu nedenle, direktifin her örneğine özgü her şeyi gerçekleştiriyoruz. İçin örnek: olaylarını takılarak , kapsamı dayalı şablonu mutasyona vs.

  • Son olarak, direktif (eklendikten sonra) üzerinde çalışırken kontrolörün canlı ve reaktif olması sağlanmalıdır DOM. Bu nedenle:

    (1) [ V ] (örn. Şablon) bağlantısını kurduktan sonra . $scopeeden bir [ E ] ve $controllereden bir [ C de] MVC

    (2) Saatler kurarak $ scope ile 2 yönlü bağlantıdan yararlanın .

    (3) $scopeçalışma zamanı sırasında şablonu izleyen şey bu olduğundan denetleyiciye saatlerin eklenmesi beklenir.

    (4) Son olarak, controllerilgili direktifler arasında iletişim kurabilmek için de kullanılır. ( Https://docs.angularjs.org/guide/directivemyTabs içindeki örnek gibi )

    (5) Bütün bunları linkişlevde de yapabileceğimiz doğru ama endişelerin ayrılmasıyla ilgili .

Bu nedenle, nihayet tüm parçalara mükemmel uyan aşağıdakiler var:

resim açıklamasını buraya girin


5
Ayrıca bu makaleyi burada yürütme sırasını anlamak için yararlı buldum: AngularJS direktifleri içinde derleme ve bağlantı işlevlerinin
nitrit

4
Harika bir açıklama. Bağlayıcı fonksiyonundan önce kontrol cihazının çağrıldığını belirtmek isteriz.
jsbisht

38
denetleyici bağlantıdan önce yürütülür
Royi Namir

10
Yığın Taşması'nın düzenlemelerin en az 6 karakter olmasını istediğini çileden çıkarıyor, bu yüzden bu cevapta yazımın yazımını düzeltmeme izin vermiyor.
user1886323

79

Kontrolörlere neden ihtiyaç duyulur

DOM'nizdeki yönergeleri yerleştirmek ve API işlevlerini üst yönergeden iç içe olanlara göstermek istediğinizde linkve arasındaki fark controllerortaya çıkar.

Gönderen docs :

En İyi Uygulama: Bir API'yi diğer yönergelere göstermek istediğinizde denetleyiciyi kullanın. Aksi takdirde bağlantı kullanın.

Diyelim ki iki direktifiniz var my-formve direktifin sadece içeride ve başka hiçbir yerde görünmesini my-text-inputistiyorsunuz .my-text-inputmy-form

Yönergesini tanımlarken o durumda, diyecekler my-text-inputo gerektirir gelen bir denetleyici parentböyle, argüman gerektiren kullanarak DOM öğesinin: require: '^myForm'. Şimdi üst elemandan denetleyicisi olacaktır injectediçine linksonra dördüncü bağımsız değişken olarak işlev $scope, element, attributes. Bu denetleyicideki işlevleri çağırabilir ve üst yönerge ile iletişim kurabilirsiniz.

Ayrıca, böyle bir kontrolör bulunmazsa, bir hata ortaya çıkar.

Bağlantıyı neden kullanmalıyım?

Üzerinde kullanılabilir linkolduğundan bir tanımlanıyorsa, controllerbu işlevi kullanmak için gerçek bir gerek yoktur . Dahası, her ikisini de tanımlarken ve ikisinin çağrılma düzenine dikkat edilmesi gerekir ( daha önce idam edilir).$scopecontrollerlinkcontrollercontroller

Bununla birlikte, Açısal yolla uyumlu olarak , çoğu DOM manipülasyonu ve 2 yollu bağlama $watchersgenellikle linkişlevde yapılırken, çocuklar için API ve $scopemanipülasyonda yapılır controller. Bu zor ve hızlı bir kural değildir, ancak bunu yapmak kodu daha modüler hale getirecek ve endişelerin ayrılmasına yardımcı olacaktır (denetleyici directivedurumu koruyacak ve linkişlev DOM+ dış bağlamaları koruyacaktır ).


Bu harika. Şimdi, sorunun ikinci kısmında bana yardımcı olabilir misiniz?
Yugal Jindle

Yani, diğer direktiflerle iletişim kurmak için kullanılabilecek bir denetleyicimiz var olduğundan. Peki, neye ihtiyacı vardı link?
Yugal Jindle

1
Cevabınız bir şekilde asıl soruya cevap vermiyor.
Yugal Jindle

1
Bir tanımladığımızda ortaya çıkan herhangi bir sorun var controllermı? Denetleyiciyi tanımlamaktan kaçınmak için neden tamamen yeni bir işlev icat etmek isteyeyim?
Yugal Jindle

1
Görünüşe göre @scalaGirl s Link artık çalışmıyor
Minato

17

controllerFonksiyon / nesne bir soyutlama model görünüşüdür-kontrolör (MVC) temsil eder. MVC hakkında yazacak yeni bir şey olmasa da, hala açısalın en önemli avantajı: endişeleri daha küçük parçalara ayırın. Ve bu tepki gerek eğer öyleyse, başka bir şey, bu kadar Modelgelen değişikliklere doğru kişi o işi yapmak için.ViewController

linkİşlev hakkındaki hikaye farklıdır, MVC'den farklı bir perspektiften geliyor. Ve bir kez controller/model/view (şablonun) sınırlarını aşmak istediğimizde gerçekten çok önemlidir .

İşleve geçirilen parametrelerle başlayalım link:

function link(scope, element, attrs) {
  • scope , bir Açısal kapsam nesnesidir.
  • öğesi , bu yönergenin eşleştiği jqLite ile sarılmış öğedir.
  • attrs , normalleştirilmiş öznitelik adlarına ve karşılık gelen değerlerine sahip bir nesnedir.

İçeriğe koymak için link, tüm direktiflerin bu başlatma işlemi adımlarından geçtiğini belirtmeliyiz: Derleme , Bağlantı . An Özü Brad Green ve Shyam Seshadri kitap Eğik JS :

Derleme aşaması (bağlantı kız kardeşi, net bir resim elde etmek için burada bahsedelim):

Bu aşamada, Angular, şablondaki tüm kayıtlı yönergeleri tanımlamak için DOM'u yürür. Her yönerge için, daha sonra DOM'u yönerge kurallarına (şablon, değiştir, ekleme, vb.) Göre dönüştürür ve varsa derleme işlevini çağırır. Sonuç, derlenmiş bir şablon işlevidir,

Bağlantı aşaması :

Görünümü dinamik hale getirmek için Angular her yönerge için bir bağlantı işlevi çalıştırır. Bağlantı işlevleri genellikle DOM'da veya modelde dinleyiciler oluşturur. Bu dinleyiciler görünümü ve modeli her zaman senkronize tutar.

Nasıl kullanılacağıyla ilgili güzel bir örnek linkburada bulunabilir: Özel Yönergeler Oluşturma . Örneğe bakın: Sayfaya "tarih-saat" ekleyen DOM'yi İşleyen bir Yönerge Oluşturma her saniye yenilenir.

DOM ile gerçek manipülasyonu gösteren, yukarıdaki zengin kaynaktan sadece çok kısa bir snippet . $ Zaman aşımı hizmetine bağlı bir işlev vardır ve ayrıca bellek sızıntılarını önlemek için yıkıcı çağrısında temizlenir

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...

3
Karşılaştırmış gibisin compilerve link. Soru, neden linkzaten ne zaman yaşadığımızı soruyorcontroller
Yugal Jindle

Kontrol cihazını bile daha ayrıntılı olarak açıklamak için cevabı uzattım. Şimdi controllervs kavramları linkdaha açık olmalı ...
Radim Köhler

1
Bu açıklama için uzlaşmaya çalışabilirim. Ama orada biraz bulanık görünüyor. İçin - açısal ekibinden birisi kendisi bunun için konuşabilir eğer onlar gidiyor görüyorsunuz nereye projelendirme, çok iyi olurdu linkya controller.
Yugal Jindle

1
Anlamak istediğim tek kısım bu (Ne zaman yeterli değil?). Ayrıca, açısal tüm faydaları alıyorum controllerve linknispeten çirkin. Yani, açısal ekibin sadece bir seçenek yerine bunun için iyi bir nedeni olmalı.
Yugal Jindle

1
Soru: Kontrolör yeterli olmadığında? Cvp: Bir JQuery eklentisi kullanmak veya belgede belirtildiği gibi JQlite özelliğini kullanmak gibi açısal bir deneyime ihtiyacınız olduğunda ( docs.angularjs.org/api/ng/function/angular.element:) , bağlantı
Hasteq
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.