Apakah tidak ada yang setara dengan $scope.emit()
atau$scope.broadcast()
di Angular?
Saya tahu EventEmitter
fungsionalitasnya, tetapi sejauh yang saya mengerti itu hanya akan memancarkan suatu peristiwa ke elemen HTML induk.
Bagaimana jika saya perlu berkomunikasi antara fx. saudara atau antara komponen di root DOM dan elemen bersarang beberapa tingkat dalam?
Jawaban:
Tidak ada yang setara dengan
$scope.emit()
atau$scope.broadcast()
dari AngularJS. EventEmitter di dalam komponen sudah dekat, tetapi seperti yang Anda sebutkan, itu hanya akan memancarkan sebuah peristiwa ke komponen induk langsung.Di Angular, ada alternatif lain yang akan saya coba jelaskan di bawah ini.
@Input () binding memungkinkan model aplikasi untuk dihubungkan dalam grafik objek yang diarahkan (root to leaves). Perilaku default dari strategi detektor perubahan komponen adalah untuk menyebarkan semua perubahan ke model aplikasi untuk semua ikatan dari komponen yang terhubung.
Selain: Ada dua jenis model: Lihat Model dan Model Aplikasi. Model aplikasi terhubung melalui @Input () binding. Model tampilan hanyalah properti komponen (tidak didekorasi dengan @Input ()) yang terikat dalam templat komponen.
Untuk menjawab pertanyaan Anda:
Bagaimana jika saya perlu berkomunikasi antara komponen saudara?
Model Aplikasi Bersama : Saudara dapat berkomunikasi melalui model aplikasi bersama (seperti sudut 1). Misalnya, ketika satu saudara kandung membuat perubahan ke model, saudara kandung lainnya yang memiliki ikatan dengan model yang sama diperbarui secara otomatis.
Component Events : Komponen child dapat memancarkan sebuah event ke komponen induk menggunakan binding @Output (). Komponen induk dapat menangani acara, dan memanipulasi model aplikasi atau model tampilan itu sendiri. Perubahan pada Model Aplikasi secara otomatis disebarkan ke semua komponen yang secara langsung atau tidak langsung mengikat ke model yang sama.
Acara Layanan : Komponen dapat berlangganan acara layanan. Misalnya, dua komponen saudara dapat berlangganan ke acara layanan yang sama dan merespons dengan memodifikasi model masing-masing. Lebih lanjut tentang ini di bawah ini.
Bagaimana saya bisa berkomunikasi antara komponen Root dan komponen yang bersarang dalam beberapa level?
$scope.broadcast()
dari Angular 1. Bagian selanjutnya menjelaskan ide ini secara lebih rinci.Contoh Layanan yang Dapat Diobservasi yang menggunakan Acara Layanan untuk Menyebarkan Perubahan
Berikut adalah contoh layanan yang dapat diamati yang menggunakan acara layanan untuk menyebarkan perubahan. Ketika TodoItem ditambahkan, layanan memancarkan acara yang memberitahukan pelanggan komponennya.
Berikut adalah bagaimana komponen root akan berlangganan acara:
Komponen anak yang bersarang beberapa level akan berlangganan acara dengan cara yang sama:
Berikut adalah komponen yang memanggil layanan untuk memicu acara (itu bisa berada di mana saja di pohon komponen):
Referensi: Ubah Deteksi dalam Angular
sumber
itemAdded$
,. Apakah itu konvensi RxJS atau sesuatu? Dari mana ini berasal?street
properti model aplikasi, tetapi karena Angular 2 mengimplementasikan deteksi perubahan dengan identitas / referensi, tidak ada perubahan yang diperbanyak (onChanges
tidak disebut), karena referensi model aplikasi tidak berubah ( lanjutan ...)Kode berikut sebagai contoh pengganti $ scope.emit () atau $ scope.broadcast () di Angular 2 menggunakan layanan bersama untuk menangani acara.
Contoh penggunaan:
Siaran:
Pendengar:
Itu dapat mendukung banyak argumen:
sumber
off(name, listener) { this.listeners[name] = this.listeners[name].filter(x => x != listener); }
Saya menggunakan layanan pesan yang membungkus rxjs
Subject
(TypeScript)Contoh Plunker: Layanan Pesan
Komponen dapat berlangganan dan menyiarkan acara (pengirim):
(penerima)
The
subscribe
metodeMessageService
pengembalian suatu rxjsSubscription
objek, yang dapat berhenti berlangganan dari seperti:Lihat juga jawaban ini: https://stackoverflow.com/a/36782616/1861779
Contoh Plunker: Layanan Pesan
sumber
Property 'filter' does not exist on type 'Subject<EventMessage>'.
this.handler.pipe(filter(...))
. Lihat operator yang memungkinkan .return this.handler.pipe( filter(message => message.type === type), map(message => message.payload) ).subscribe(callback);
JANGAN Gunakan EventEmitter untuk komunikasi layanan Anda.
Anda harus menggunakan salah satu dari tipe yang Dapat Diobservasi. Saya pribadi suka BehaviorSubject.
Contoh sederhana:
Anda dapat melewati kondisi awal, di sini saya melewati nol
Ketika Anda ingin memperbarui subjek
Amati dari setiap layanan atau komponen dan bertindaklah ketika mendapat pembaruan baru.
Berikut ini informasi lebih lanjut. .
sumber
Anda dapat menggunakan
EventEmitter ataudapat diamati untuk membuat layanan eventbus yang Anda daftarkan dengan DI. Setiap komponen yang ingin berpartisipasi hanya meminta layanan sebagai parameter konstruktor dan memancarkan dan / atau berlangganan acara.Lihat juga
sumber
Cara favorit saya untuk melakukannya adalah dengan menggunakan subjek perilaku atau emitor acara (hampir sama) di layanan saya untuk mengontrol semua subkomponen saya.
Menggunakan angular cli, jalankan ng gs untuk membuat layanan baru kemudian gunakan BehaviorSubject atau EventEmitter
Ketika Anda melakukan itu, setiap komponen yang menggunakan layanan Anda sebagai penyedia akan menyadari perubahan tersebut. Cukup berlangganan ke hasil seperti yang Anda lakukan dengan eventEmitter;)
sumber
Saya telah membuat sampel pub-sub di sini:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
Idenya adalah untuk menggunakan Subjek RxJs untuk memasang Pengamat dan dan Observable sebagai solusi umum untuk memancarkan dan berlangganan acara kustom. Dalam sampel saya, saya menggunakan objek pelanggan untuk tujuan demo
Berikut ini adalah demo langsung: http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
sumber
Ini versi saya:
menggunakan:
}
memancarkan:
sumber
Kami menerapkan arable ngModelChange yang dapat diobservasi yang mengirimkan semua perubahan model melalui emitor acara yang Anda instantiate di komponen Anda sendiri. Anda hanya harus mengikat emitor acara Anda ke arahan.
Lihat: https://github.com/atomicbits/angular2-modelchangeobservable
Di html, ikat emitor acara Anda (countryChanged dalam contoh ini):
Di komponen naskah Anda, lakukan beberapa operasi async pada EventEmitter:
sumber
Acara Layanan: Komponen dapat berlangganan acara layanan. Misalnya, dua komponen saudara dapat berlangganan ke acara layanan yang sama dan merespons dengan memodifikasi model masing-masing. Lebih lanjut tentang ini di bawah ini.
Tetapi pastikan untuk berhenti berlangganan pada yang menghancurkan komponen induk.
sumber