Saya ingin menutup dropdown menu login saya ketika pengguna mengklik di mana saja di luar dropdown itu, dan saya ingin melakukannya dengan Angular2 dan dengan "pendekatan" Angular2 ...
Saya telah mengimplementasikan solusi, tetapi saya benar-benar tidak merasa yakin dengan itu. Saya pikir pasti ada cara termudah untuk mencapai hasil yang sama, jadi jika Anda punya ide ... mari kita bahas :)!
Inilah implementasi saya:
Komponen dropdown:
Ini adalah komponen untuk dropdown saya:
- Setiap kali komponen ini disetel ke terlihat, (Misalnya: ketika pengguna mengklik tombol untuk menampilkannya) ia berlangganan ke subjek "global" rxjs yang disimpan oleh userMenu di dalam SubjectsService .
- Dan setiap kali disembunyikan, ia berhenti berlangganan ke subjek ini.
- Setiap klik di mana saja di dalam templat komponen ini memicu metode onClick () , yang hanya menghentikan peristiwa yang menggelegak ke atas (dan komponen aplikasi)
Ini kodenya
export class UserMenuComponent {
_isVisible: boolean = false;
_subscriptions: Subscription<any> = null;
constructor(public subjects: SubjectsService) {
}
onClick(event) {
event.stopPropagation();
}
set isVisible(v) {
if( v ){
setTimeout( () => {
this._subscriptions = this.subjects.userMenu.subscribe((e) => {
this.isVisible = false;
})
}, 0);
} else {
this._subscriptions.unsubscribe();
}
this._isVisible = v;
}
get isVisible() {
return this._isVisible;
}
}
Komponen aplikasi:
Di sisi lain, ada komponen aplikasi (yang merupakan induk dari komponen dropdown):
- Komponen ini menangkap setiap acara klik dan memancarkan pada subjek rxjs yang sama ( userMenu )
Ini kodenya:
export class AppComponent {
constructor( public subjects: SubjectsService) {
document.addEventListener('click', () => this.onClick());
}
onClick( ) {
this.subjects.userMenu.next({});
}
}
Apa yang mengganggu saya:
- Saya tidak merasa benar-benar nyaman dengan gagasan memiliki Subjek global yang bertindak sebagai penghubung antara komponen-komponen itu.
- The setTimeout : Hal ini diperlukan karena di sini adalah apa yang terjadi sebaliknya jika pengguna mengklik tombol yang menunjukkan dropdown:
- Pengguna mengklik tombol (yang bukan merupakan bagian dari komponen dropdown) untuk menampilkan dropdown.
- Dropdown ditampilkan dan segera berlangganan ke subjek userMenu .
- Acara klik menggembung ke komponen aplikasi dan tertangkap
- Komponen aplikasi memancarkan suatu peristiwa pada subjek userMenu
- Komponen dropdown menangkap tindakan ini pada userMenu dan menyembunyikan dropdown.
- Pada akhirnya dropdown tidak pernah ditampilkan.
Set timeout ini menunda langganan ke akhir pergantian kode JavaScript saat ini yang menyelesaikan masalah, tetapi menurut cara yang sangat elegan menurut saya.
Jika Anda tahu solusi yang lebih bersih, lebih baik, lebih cerdas, lebih cepat atau lebih kuat, beri tahu saya :)!