Angular JS: Apa perlunya fungsi tautan direktif ketika kita sudah memiliki pengontrol direktif dengan cakupan?

199

Saya perlu melakukan beberapa operasi pada lingkup dan template. Tampaknya saya bisa melakukan itu baik dalam linkfungsi atau controllerfungsi (karena keduanya memiliki akses ke ruang lingkup).

Kapan itu terjadi ketika saya harus menggunakan linkfungsi dan bukan controller?

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 */ }
    };
}

Juga, saya mengerti itu linkadalah dunia non-sudut. Jadi, saya bisa menggunakan $watch, $digestdan $apply.

Apa pentingnya linkfungsi, ketika kita sudah memiliki pengontrol?

Yugal Jindle
sumber
9
Apa yang Anda maksud dengan " Juga, saya mengerti bahwa tautan adalah dunia non-sudut. Jadi, saya bisa menggunakan $watch, $digestdan $apply. "?
musically_ut
2
Di dalam linkkita tidak melihat sihir sudut. yaitu tidak ada binding 2 way, dll. Hanya saja kita memiliki api sudut yang tersedia untuk digunakan.
Yugal Jindle

Jawaban:

299

Setelah saya awal perjuangan dengan linkdan controllerfungsi dan membaca cukup banyak tentang mereka, saya pikir sekarang aku punya jawabannya.

Pertama mari kita pahami ,

Bagaimana arahan sudut bekerja secara singkat:

  • Kita mulai dengan templat (sebagai string atau dimuat ke string)

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

  • Sekarang, ini templateStringdibungkus sebagai elemen sudut

    var el = angular.element(templateString);

  • Dengan el, sekarang kami mengompilasinya $compileuntuk mendapatkan kembali fungsi tautan .

    var l = $compile(el)

    Inilah yang terjadi,

    • $compile menelusuri seluruh templat dan mengumpulkan semua arahan yang dikenali.
    • Semua arahan yang ditemukan dikompilasi secara rekursif dan linkfungsinya dikumpulkan.
    • Kemudian, semua linkfungsi dibungkus dengan linkfungsi baru dan dikembalikan sebagai l.
  • Akhirnya, kami menyediakan scopefungsi untuk fungsi l(tautan) ini yang selanjutnya mengeksekusi fungsi tautan yang dibungkus dengan ini scopedan elemen-elemen terkait.

    l(scope)

  • Ini menambahkan templatesebagai simpul baru ke DOMdan memanggil controlleryang menambahkan arlojinya ke lingkup yang dibagi dengan templat di DOM.

masukkan deskripsi gambar di sini

Membandingkan compile vs link vs controller :

  • Setiap arahan dikompilasi hanya sekali dan fungsi tautan dipertahankan untuk digunakan kembali. Oleh karena itu, jika ada sesuatu yang berlaku untuk semua instance dari direktif harus dilakukan di dalam compilefungsi directive .

  • Sekarang, setelah kompilasi kita memiliki linkfungsi yang dieksekusi ketika melampirkan templat ke DOM . Jadi, oleh karena itu kami melakukan semua yang spesifik untuk setiap instance dari arahan. Misalnya: melampirkan peristiwa , memutasikan template berdasarkan cakupan , dll.

  • Akhirnya, controller dimaksudkan agar tersedia untuk hidup dan reaktif sementara arahan bekerja pada DOM(setelah terpasang). Karena itu:

    (1) Setelah mengatur tampilan [ V ] (yaitu templat) dengan tautan. $scopeadalah [ M ] $controllerkami dan [ C ] kami di MVC

    (2) Manfaatkan pengikatan 2 arah dengan $ scope dengan mengatur jam tangan.

    (3) $scopejam tangan diharapkan akan ditambahkan dalam pengontrol karena ini adalah apa yang menonton template selama waktu berjalan.

    (4) Akhirnya, controllerjuga digunakan untuk dapat berkomunikasi di antara arahan terkait. (Seperti myTabscontoh di https://docs.angularjs.org/guide/directive )

    (5) Memang benar bahwa kita bisa melakukan semua ini dalam linkfungsinya tetapi juga tentang pemisahan keprihatinan .

Oleh karena itu, akhirnya kami memiliki yang berikut ini yang cocok dengan semua bagian dengan sempurna:

masukkan deskripsi gambar di sini

Yugal Jindle
sumber
5
Saya juga menemukan artikel ini berguna untuk memahami urutan eksekusi di sini: Intisari fungsi kompilasi dan tautan di dalam arahan AngularJS
BobbyA
4
Penjelasan yang bagus. Ingin menyebutkan bahwa pengontrol dipanggil sebelum fungsi tautan.
jsbisht
38
controller dijalankan sebelum tautan
Royi Namir
10
Itu membuat saya marah bahwa Stack Overflow menuntut bahwa pengeditan setidaknya 6 karakter, sehingga tidak memungkinkan saya untuk memperbaiki ejaan mari dalam jawaban ini.
user1886323
79

Mengapa pengendali dibutuhkan

Perbedaan antara linkdan controllerikut bermain ketika Anda ingin menyusun arahan di DOM Anda dan mengekspos fungsi API dari arahan induk ke arahan bersarang.

Dari dokumen :

Praktik Terbaik: gunakan pengontrol saat Anda ingin mengekspos API ke arahan lain. Kalau tidak gunakan tautan.

Katakan Anda ingin memiliki dua arahan my-formdan my-text-inputdan Anda ingin my-text-inputarahan hanya muncul di dalam my-formdan di tempat lain.

Dalam hal ini, Anda akan mengatakan sementara mendefinisikan direktif my-text-inputyang membutuhkan kontroler dari parentelemen DOM menggunakan membutuhkan argumen, seperti ini: require: '^myForm'. Sekarang controller dari elemen induk akan injectedke linkfungsi sebagai argumen keempat, berikut $scope, element, attributes. Anda dapat memanggil fungsi pada pengontrol itu dan berkomunikasi dengan arahan induk.

Selain itu, jika pengontrol seperti itu tidak ditemukan, kesalahan akan dinaikkan.

Mengapa menggunakan tautan?

Tidak ada kebutuhan nyata untuk menggunakan linkfungsi jika ada yang mendefinisikan controllersejak $scopetersedia di Internet controller. Selain itu, ketika mendefinisikan keduanya linkdan controller, seseorang perlu berhati-hati tentang urutan doa keduanya ( controllerdieksekusi sebelumnya).

Namun, sesuai dengan cara Angular , sebagian besar manipulasi DOM dan pengikatan 2 arah $watchersbiasanya dilakukan dalam linkfungsi sedangkan API untuk anak-anak dan $scopemanipulasi dilakukan dalam controller. Ini bukan aturan yang keras dan cepat, tetapi hal itu akan membuat kode lebih modular dan membantu dalam pemisahan masalah (pengontrol akan mempertahankan directivestatus dan linkfungsi akan mempertahankan DOM+ binding luar).

musically_ut
sumber
Itu hebat. Sekarang, bisakah Anda membantu saya dengan bagian kedua dari pertanyaan?
Yugal Jindle
Maksud saya, karena kami memiliki controller yang dapat digunakan untuk berkomunikasi dengan arahan lain. Jadi, apa perlunya link?
Yugal Jindle
1
Entah bagaimana jawaban Anda tidak menjawab pertanyaan yang sebenarnya.
Yugal Jindle
1
Apakah ada masalah yang terjadi ketika kita mendefinisikan controller? Mengapa saya ingin menciptakan fungsi yang sama sekali baru hanya untuk menghindari mendefinisikan controller?
Yugal Jindle
1
tampaknya tautan @scalaGirl s tidak berfungsi lagi
Minato
17

The controllerFungsi / object merupakan abstraksi model-view-controller (MVC). Meskipun tidak ada yang baru untuk menulis tentang MVC, itu masih merupakan kemajuan sudut pandang yang paling signifikan: pisahkan masalah menjadi bagian-bagian yang lebih kecil. Dan itu, tidak lebih, jadi jika Anda perlu untuk bereaksi pada Modelperubahan yang datang dari Viewyang Controlleradalah hak orang untuk melakukan pekerjaan itu.

Cerita tentang linkfungsi berbeda, itu datang dari sudut pandang yang berbeda dari MVC. Dan benar-benar penting, sekali kita ingin melewati batas controller/model/view (templat) .

Mari kita mulai dengan parameter yang diteruskan ke linkfungsi:

function link(scope, element, attrs) {
  • scope adalah objek lingkup Angular.
  • element adalah elemen terbungkus jqLite yang sesuai dengan arahan ini.
  • attrs adalah objek dengan nama atribut yang dinormalisasi dan nilainya yang sesuai.

Untuk memasukkannya linkke dalam konteks, kita harus menyebutkan bahwa semua arahan sedang melalui langkah-langkah proses inisialisasi ini: Kompilasi , Tautan . Ekstrak dari buku Brad Green dan Shyam Seshadri Angular JS :

Fase kompilasi (saudara perempuan tautan, sebut saja di sini untuk mendapatkan gambar yang jelas):

Dalam fase ini, Angular berjalan DOM untuk mengidentifikasi semua arahan terdaftar dalam template. Untuk setiap arahan, itu kemudian mengubah DOM berdasarkan aturan arahan (templat, ganti, transclude, dan sebagainya), dan memanggil fungsi kompilasi jika ada. Hasilnya adalah fungsi template yang dikompilasi,

Fase tautan :

Untuk membuat tampilan dinamis, Angular kemudian menjalankan fungsi tautan untuk setiap arahan. Fungsi tautan biasanya membuat pendengar pada DOM atau model. Pendengar ini menjaga tampilan dan model tetap sinkron setiap saat.

Sebuah contoh yang bagus bagaimana cara menggunakan linkdapat ditemukan di sini: Membuat Arahan Kustom . Lihat contoh: Membuat Arahan yang Memanipulasi DOM , yang memasukkan "tanggal-waktu" ke halaman, disegarkan setiap detik.

Cuplikan singkat dari sumber kaya di atas, menunjukkan manipulasi nyata dengan DOM. Ada fungsi terhubung ke layanan timeout $, dan juga dihapus dalam panggilan destruktor untuk menghindari kebocoran memori

.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);
 });

 ...
Radim Köhler
sumber
3
Anda tampaknya telah membandingkan compilerdan link. Pertanyaan mereka adalah bertanya mengapa linkketika kita sudah punyacontroller
Yugal Jindle
Saya telah memperluas jawaban untuk menjelaskan bahkan pengontrol secara lebih terperinci. Sekarang konsep controllervs linkharus lebih jelas ...
Radim Köhler
1
Saya bisa mencari penyelesaian untuk penjelasan itu. Tapi sepertinya agak buram di sana. Akan lebih bagus jika seseorang dari tim sudut itu sendiri dapat berbicara untuk itu, memproyeksikan kemana mereka melihatnya - ke linkatau controller.
Yugal Jindle
1
Itulah satu-satunya bagian yang ingin saya mengerti (Kapan itu tidak cukup?). Ditambah lagi, saya mendapatkan semua manfaat sudut controllerdan linkrelatif jelek. Jadi, tim sudut harus memiliki alasan yang baik untuk itu, bukan hanya pilihan.
Yugal Jindle
1
Pertanyaan: Kapan Kontroler tidak memadai? Jawab: Ketika Anda membutuhkan pengalaman Angular, seperti menggunakan plugin JQuery atau menggunakan fitur JQlite sebagaimana disebutkan dalam dokumen ( docs.angularjs.org/api/ng/function/angular.element:) , maka Anda perlu tautan
Hasteq