Apa cara yang benar untuk berkomunikasi antar pengendali?
Saat ini saya menggunakan fudge mengerikan yang melibatkan window
:
function StockSubgroupCtrl($scope, $http) {
$scope.subgroups = [];
$scope.handleSubgroupsLoaded = function(data, status) {
$scope.subgroups = data;
}
$scope.fetch = function(prod_grp) {
$http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded);
}
window.fetchStockSubgroups = $scope.fetch;
}
function StockGroupCtrl($scope, $http) {
...
$scope.select = function(prod_grp) {
$scope.selectedGroup = prod_grp;
window.fetchStockSubgroups(prod_grp);
}
}
Jawaban:
Sunting : Masalah yang dibahas dalam jawaban ini telah diatasi dalam angular.js versi 1.2.7 .
$broadcast
sekarang hindari menggelegak atas cakupan yang tidak terdaftar dan berjalan secepat $ emit.Jadi, sekarang Anda dapat:
$broadcast
dari$rootScope
$on
dari lokal$scope
yang perlu tahu tentang acara tersebutJawaban Asli Di Bawah Ini
Saya sangat menyarankan untuk tidak menggunakan
$rootScope.$broadcast
+$scope.$on
melainkan$rootScope.$emit
+$rootScope.$on
. Yang pertama dapat menyebabkan masalah kinerja serius seperti yang diangkat oleh @numan. Itu karena acara tersebut akan menyebar melalui semua ruang lingkup.Namun, yang terakhir (menggunakan
$rootScope.$emit
+$rootScope.$on
) tidak menderita ini dan karena itu dapat digunakan sebagai saluran komunikasi yang cepat!Dari dokumentasi sudut
$emit
:Karena tidak ada ruang lingkup di atas
$rootScope
, tidak ada gelembung yang terjadi. Sangat aman untuk menggunakan$rootScope.$emit()
/$rootScope.$on()
sebagai EventBus.Namun, ada satu gotcha saat menggunakannya dari dalam Controllers. Jika Anda langsung mengikat
$rootScope.$on()
dari dalam controller, Anda harus membersihkan sendiri mengikat ketika lokal Anda$scope
hancur. Ini karena pengontrol (berbeda dengan layanan) dapat dipakai berkali-kali selama masa aplikasi yang akan menghasilkan binding yang akhirnya membuat kebocoran memori di semua tempat :)Untuk unregister, hanya mendengarkan pada Anda
$scope
's$destroy
acara dan kemudian memanggil fungsi yang dikembalikan oleh$rootScope.$on
.Saya akan mengatakan, itu bukan hal yang sangat spesifik karena berlaku untuk implementasi EventBus lain juga, bahwa Anda harus membersihkan sumber daya.
Namun, Anda dapat membuat hidup Anda lebih mudah untuk kasus-kasus itu. Misalnya, Anda dapat menambal monyet
$rootScope
dan memberikannya$onRootScope
yang berlangganan acara yang dipancarkan di$rootScope
tetapi juga secara langsung membersihkan pawang ketika lokal$scope
dihancurkan.Cara paling bersih untuk menambal monyet
$rootScope
untuk memberikan$onRootScope
metode seperti itu akan melalui dekorator (blok run mungkin akan melakukannya dengan baik juga tapi pssst, jangan bilang siapa-siapa)Untuk memastikan
$onRootScope
properti tidak muncul secara tak terduga saat menghitung lebih dari,$scope
kami menggunakanObject.defineProperty()
dan mengaturenumerable
untukfalse
. Perlu diingat bahwa Anda mungkin memerlukan shim ES5.Dengan metode ini, kode pengontrol dari atas dapat disederhanakan menjadi:
Jadi sebagai hasil akhir dari semua ini saya sangat menyarankan Anda untuk menggunakan
$rootScope.$emit
+$scope.$onRootScope
.Btw, saya mencoba meyakinkan tim sudut untuk mengatasi masalah dalam inti sudut. Ada diskusi yang terjadi di sini: https://github.com/angular/angular.js/issues/4574
Berikut adalah jsperf yang menunjukkan berapa banyak dampak perf yang
$broadcast
dibawa ke meja dalam skenario yang layak hanya dengan 100$scope
's.http://jsperf.com/rootscope-emit-vs-rootscope-broadcast
sumber
The atas jawabannya di sini adalah bekerja di sekitar dari masalah sudut yang tidak ada lagi (setidaknya dalam versi> 1.2.16 dan "mungkin sebelumnya") sebagai @zumalifeguard telah disebutkan. Tetapi saya pergi membaca semua jawaban ini tanpa solusi yang sebenarnya.
Bagi saya sepertinya jawabannya sekarang
$broadcast
dari$rootScope
$on
dari lokal$scope
yang perlu tahu tentang acara tersebutJadi untuk mempublikasikan
Dan berlangganan
Plunker
Controller As
sintaks baruJika Anda mendaftarkan pendengar di lokal
$scope
, itu akan dihancurkan secara otomatis dengan$destroy
sendirinya ketika pengontrol terkait dihapus.sumber
controllerAs
sintaks? Saya dapat menggunakan$rootScope
pelanggan untuk mendengarkan acara tersebut, tetapi saya hanya ingin tahu apakah ada pola yang berbeda.$scope
secara eksplisit. John Papa menulis tentang peristiwa yang menjadi "pengecualian" dari aturannya yang biasa untuk mencegah$scope
"pengontrol" nya (saya menggunakan tanda kutip karena ketika ia menyebutkanController As
masih memiliki$scope
, itu hanya di bawah kap).controller as
alternatif sintaksis seperti yang diminta. Saya harap itulah yang Anda maksudkan.Menggunakan $ rootScope. $ Broadcast dan $ scope. $ On untuk komunikasi PubSub.
Juga, lihat posting ini: AngularJS - Communicating Between Controllers
sumber
$rootScope
dan$watch
. Tidak yakin itu perbaikan apa pun.Karena defineProperty memiliki masalah kompatibilitas browser, saya pikir kita dapat berpikir tentang menggunakan layanan.
dan gunakan di controller seperti ini:
pengontrol 1
pengontrol 2
sumber
GridLinked memposting solusi PubSub yang tampaknya dirancang dengan cukup baik. Layanan dapat ditemukan di sini .
Juga diagram layanan mereka:
sumber
Sebenarnya menggunakan memancarkan dan menyiarkan tidak efisien karena peristiwa menggelembung naik dan turunnya hierarki ruang lingkup yang dapat dengan mudah menurunkan ke kinerja bottlement untuk aplikasi yang kompleks.
Saya akan menyarankan untuk menggunakan layanan. Inilah cara saya baru-baru ini mengimplementasikannya di salah satu proyek saya - https://gist.github.com/3384419 .
Ide dasar - daftarkan bus pubsub / event sebagai layanan. Kemudian menyuntikkan eventbus itu di mana pun Anda perlu berlangganan atau menerbitkan acara / topik
sumber
$rootScope.$emit()
hanya gelembung ke atas. Namun, karena tidak ada ruang lingkup di atas,$rootScope
tidak ada yang perlu ditakutkan. Jadi jika Anda hanya menggunakan$rootScope.$emit()
dan$rootScope.$on()
Anda akan memiliki sistem EventBus lebar cepat.$rootScope.$on()
di dalam controller Anda, Anda harus membersihkan acara yang mengikat karena jika tidak mereka akan meringkas karena itu membuat yang baru setiap kali controller instantiated dan mereka tidak dihancurkan secara otomatis untuk Anda karena Anda mengikat$rootScope
secara langsung.Menggunakan metode get and set dalam layanan, Anda dapat mengirimkan pesan antar pengontrol dengan sangat mudah.
dalam HTML HTML Anda dapat memeriksa seperti ini
sumber
Mengenai kode asli - tampaknya Anda ingin berbagi data antar cakupan. Untuk membagikan Data atau Status antara $ scope, saran dokter menggunakan layanan:
Ref: Angular Documents tautan di sini
sumber
Saya sebenarnya sudah mulai menggunakan Postal.js sebagai bus pesan antara pengontrol.
Ada banyak manfaat sebagai bus pesan seperti binding gaya AMQP, cara pos dapat mengintegrasikan w / iFrames dan soket web, dan banyak hal lainnya.
Saya menggunakan dekorator untuk menyiapkan pos di
$scope.$bus
...Berikut ini tautan ke posting blog tentang topik ini ...
http://jonathancreamer.com/an-angular-event-bus-with-postal-js/
sumber
Ini adalah bagaimana saya melakukannya dengan Pabrik / Layanan dan injeksi ketergantungan sederhana (DI) .
sumber
Saya menyukai cara bagaimana
$rootscope.emit
digunakan untuk mencapai komunikasi antar. Saya menyarankan solusi yang efektif dan bersih tanpa mencemari ruang global.sumber
Inilah cara cepat dan kotor.
Berikut adalah contoh fungsi untuk ditambahkan di dalam salah satu pengontrol saudara:
dan tentu saja inilah HTML Anda:
sumber
$rootScope
?Mulai sudut 1,5 dan fokus pengembangan berbasis komponen itu. Cara yang disarankan untuk komponen untuk berinteraksi adalah melalui penggunaan properti 'wajib' dan melalui binding properti (input / output).
Komponen akan memerlukan komponen lain (misalnya komponen root) dan mendapatkan referensi ke pengontrolnya:
Anda kemudian dapat menggunakan metode komponen root di komponen anak Anda:
Ini adalah fungsi pengontrol komponen root:
Berikut ini adalah gambaran arsitektur lengkap: Komunikasi Komponen
sumber
Anda dapat mengakses fungsi halo ini di mana saja di modul
Kontroler satu
pengontrol kedua
Info lebih lanjut di sini
sumber
Saya akan membuat layanan dan menggunakan notifikasi.
Karena pada titik mana pun, Layanan Notifikasi adalah singleton, maka ia harus dapat menyediakan data yang tetap ada.
Semoga ini membantu
sumber
Anda dapat menggunakan layanan bawaan AngularJS
$rootScope
dan menyuntikkan layanan ini di kedua pengontrol Anda. Anda kemudian dapat mendengarkan acara yang dipecat pada objek $ rootScope.$ rootScope menyediakan dua pengirim acara yang disebut
$emit and $broadcast
yang bertanggung jawab untuk mengirim acara (mungkin acara khusus) dan menggunakan$rootScope.$on
fungsi untuk menambah pendengar acara.sumber
Anda harus menggunakan Layanan, karena
$rootscope
akses dari seluruh Aplikasi, dan itu menambah beban, atau Anda menggunakan rootparams jika data Anda tidak lebih.sumber
sumber
Anda dapat melakukannya dengan menggunakan peristiwa sudut yang $ emit dan $ broadcast. Sesuai pengetahuan kami, ini adalah cara terbaik, efisien dan efektif.
Pertama kita memanggil fungsi dari satu pengontrol.
Anda juga dapat menggunakan $ rootScope sebagai pengganti $ scope. Gunakan pengontrol Anda sesuai.
sumber