Despachando eventos en el navegador
Entonces básicamente la documentación de livewire indica que hay que hacer algo como esto:
$this->dispatchBrowserEvent('name-updated', ['newName' => $value]);
Y con javascript podemos detectar ese evento:
<script>
window.addEventListener('name-updated', event => {
alert('Name updated to: ' + event.detail.newName);
})
</script>
Ejemplo práctico
Supongamos que queremos levantar una notificación cuando se ejecuta una acción con un componente: Lo que tenemos que hacer es despachar el evento con ciertas características que nos permitan hacer de nuestra notificación funcional y para eso haremos esto:
$this->dispatchBrowserEvent('notification', [
'body' => 'El registro fue actualizado correctamente',
'timeout' => 4000
]);
Aca basicamente le indicamos a nuestra notificación que va a tener un cuerpo (body) y un tiempo de espera (timeout) de 4 segundos para que se cierre automáticamente. Y nuestra notificacion va a lucir de esta manera:
<div
x-data="{body: ''}"
x-show="body.length"
x-cloak
x-on:notification.window="body = $event.detail.body; setTimeout(() => body = '', $event.detail.timeout || 2000)"
class="fixed inset-0 flex px-4 py-6 items-start pointer-events-none">
<div class="w-full flex flex-col items-center space-y-4">
<div class="max-w-sm w-full bg-gray-900 rounded-lg pointer-events-auto">
<div class="p-4 flex items-center">
<div class="ml-2 w-0 flex-1 text-white">
<span x-text="body"></span>
</div>
<button class="inline-flex text-gray-400" x-on:click="body = ''">
<span class="sr-only">Close</span>
<span class="text-2xl">×</span>
</button>
</div>
</div>
</div>
</div>
DRY
También podemos re usar la misma notificación sin importar que estemos livewire, por ejemplo, en alguna parte de nuestra aplicación podemos tener algo como esto:
session()->flash('notification', 'Texto de notificación');
Los cambios que tenemos que hacer son los siguientes:
<div
x-data="{body: ''}"
x-show="body.length"
x-cloak
x-on:notification.window="body = $event.detail.body; setTimeout(() => body = '', $event.detail.timeout || 2000)"
class="fixed inset-0 flex px-4 py-6 items-start pointer-events-none"
x-init="
@if (session()->has('notification'))
window.onload = () => {
window.dispatchEvent(new CustomEvent('notification', {
detail: {
body: '{{ session('notification') }}',
timeout: 3000
}
}))
}
@endif
"
>
<div class="w-full flex flex-col items-center space-y-4">
<div class="max-w-sm w-full bg-gray-900 rounded-lg pointer-events-auto">
<div class="p-4 flex items-center">
<div class="ml-2 w-0 flex-1 text-white">
<span x-text="body"></span>
</div>
<button class="inline-flex text-gray-400" x-on:click="body = ''">
<span class="sr-only">Close</span>
<span class="text-2xl">×</span>
</button>
</div>
</div>
</div>
</div>
Nota: esto lo saque de un curso de https://codecourse.com/