Alpinejs - Komunikasi antar komponen di Laravel
Laravel memiliki fitur komponen. saya menggunakan fitur ini saat :
- Suatu komponen bisa reuseable. misal komponen input tanggal. ini bisanya dugunakan di berbagai form yang membutuhkan input tanggal
- Jika satu halaman memliki banyak kompnen seperti ada komponen tabel dan detail row. Sehingga agar terlihat ringkas dan mudah saat maintain saya memisahkan menjadi 2 file yaitu table.blade.php sebagai parent dan detail_row.blade.php sebagai child
Maka disini akan muncul kendala saat menggunakan alipinejs. yaitu bagaimana parent dan child komponen bisa saling berbagi data ?
pada awalnya saya mengira alpinejs bisa seperti Vue yang dengan mudah bisa berbagi data antar komponen. tapi ternyata itulah salah satu kelamahan Alpinejs, setidaknya hingga artikel ini ditulis.
Tapi tenang alpinejs punya solusinya walaupun tidak se fluid Vue yaitu dengan menggunakan x-ref untuk komunikasi antara parent ke child. apa itu ?
Yaitu kita memodifikasi isi atau attrubute suatu komponen atau DOM dengan cara javascript atau jquery. jika di jquery kita memanggil suatu DOM dengan id atau class sedangkan di alpinejs kita memakai x-ref
Sedangkan komunikasi antara child dan parent menggunakan $dispatch. apa itu ?
adalah fitur di Alpine.js yang digunakan untuk mengirim custom event dari satu elemen ke elemen lain — biasanya dari child ke parent — agar bisa terjadi komunikasi antar komponen.
Hmmm... apa ada di alpinejs suatu fitur yang bisa komunikasi parent ke child dan sebaliknya ?
Jawabannya ada namanya $store. Selain itu store memiliki kelebihan lain dibanding x-ref dan $dispatch yaitu perubahan data di store bisa memicu reaktif. Lalu kenapa tidak pakai store saja ? karena store juga punya kelemahan dan akan kita bahas di artikel selanjutnya
Berikut contoh perbedaan implementasinya
<div id="divJquery" class="classJquery" x-ref="refAlpinejs" >
Konten dikelolola JS
</div>
//JQury
$("#divJquery").html("ini ID Jquery")
$(".classJquery").html("ini Class Jquery")
//Alpinejs
$refs.refAlpinejs.innerHTML = "Ini Alpinejs"Parent ke Child
Untuk penerapannya ada sedikit perbedaan kita harus membuat function yang bisa passing data $refs. sehingga DOM tidak bisa diakses langsung menggunakan $refs harus lewat paramter function. Perhatikan pada kode dibawah ini.
Contoh implementasi di komponen laravel. berikut adalah table.blade.php sebagai parent.
<div x-data="tableKomponen()">
<div>
Table
</div>
<div>
Detail Row
<button x-on:click="setDetail($refs)">Lihat Detail</button>
<x-detail_row/> <- ini tag untuk memanggil komponen child di laravel
</div>
</div>
<script>
function tableKomponen(){
return {
loading: true,
setDetailRow(ref){
ref.detailRow.innerHTML = "Ini Detail Row"
}
}
}
</script>Berikut adalah detail_row.blade.php sebagai child
<div x-ref="detailRow">
Isi detail table
</div>Penutup
Dari contoh diatas bisa kita simpulkan x-ref memiliki pendekatan yang sama dengan jquery dalam hal mengakses suatu DOM. Tapi perbedaannya jquery memilki berbagai fuction yang praktis untuk modifikasi seperti html() dan lain-lain. Sedangkan x-ref harus menggunakan function yang disediakan oleh javascript seperti innerHTML dan lain-lain
Child ke Parent
berikut parent component
<div x-data @child-event.window="handleChildEvent($event.detail)">
<h1>Parent Component</h1>
<!-- Komponen Child -->
<x-child-comp />
</div>
<script>
function handleChildEvent(detail) {
alert('Event dari child: ' + detail.message);
}
</script>
child component
<div x-data>
<button @click="$dispatch('child-event', { message: 'Halo dari child!' })">
Kirim Event ke Parent
</button>
</div>
Keterangan :
x-child-compadalah komponen Blade yang berisi Alpine.js- Di dalam child, kita gunakan
$dispatch('child-event', { message: '...' }) - Parent menangkap event dengan
@child-event.windowdan bisa akses data lewat$event.detail.