Jedną z najciekawszych i najważniejszych funkcjonalności Livewire jest mechanizm zdarzeń (events), który umożliwia komunikację między różnymi komponentami. Dzięki temu możesz stworzyć złożoną architekturę aplikacji, w której poszczególne elementy (komponenty) przekazują sobie dane i reagują na zmiany w czasie rzeczywistym, bez konieczności pisania dużych ilości kodu JavaScript.
W tym artykule przyjrzymy się, jak działa mechanizm zdarzeń w Livewire, omówimy metody takie jak emit() i emitTo(), poznamy listeners, a także zobaczymy, jak komponować aplikację w oparciu o wiele komponentów Livewire. Artykuł jest kontynuacją poprzednich tematów:
Rola zdarzeń w Livewire
W Livewire możesz wysyłać zdarzenia (emit, emitTo, dispatchBrowserEvent) z jednego komponentu do innego lub do przeglądarki. Dzięki temu możesz:
- Zaktualizować inny komponent po wykonaniu określonej akcji (np. po dodaniu zadania w jednym komponencie, odświeżyć listę w drugim komponencie).
- Komunikować się między komponentami rodzic-dziecko.
- Tworzyć architekturę, w której wiele różnych komponentów reaguje na to samo zdarzenie.
- Wywoływać zdarzenia w przeglądarce, np. do wyświetlenia natywnych powiadomień (alertów).
Metody emit() i emitTo()
emit('nazwaZdarzenia', $parametry...)– pozwala wyemitować zdarzenie o podanej nazwie. Każdy komponent, który ma w$listenerszdefiniowaną reakcję na to zdarzenie, może na nie zareagować.emitTo('nazwaKomponentu', 'nazwaZdarzenia', $parametry...)– pozwala skierować zdarzenie bezpośrednio do konkretnego komponentu Livewire (zdefiniowanego nazwą klasy lub aliasem komponentu).
$listeners
W komponencie, który ma reagować na zdarzenia, definiujemy tablicę $listeners, która określa listę „obsługiwanych” nazw zdarzeń oraz metod, jakie mają być wywołane:
protected $listeners = [
'zadanieUtworzone' => 'odswiezListeZadan'
];
W tym przykładzie, gdy dany komponent otrzyma zdarzenie o nazwie zadanieUtworzone, wywoła metodę odswiezListeZadan.
Komunikacja między rodzicem a dziećmi
W typowym scenariuszu, gdy mamy komponent rodzica i dzieci, można wywoływać metody dzieci poprzez:
emitTo(), gdzie jako nazwę komponentu podajemy unikalną nazwę wystąpienia lub alias.- Bezpośrednie przekazanie danych do widoku rodzica, jeśli logika nie wymaga stricte zdarzeń.
- Możliwe jest również „bubble’owanie” zdarzeń do góry (od dziecka do rodzica), jeśli komponent dziecko użyje
emitUp('nazwaZdarzenia').
Porady dotyczące projektowania struktury komponentów
- Podział na mniejsze komponenty – zamiast jednego dużego komponentu, warto dzielić aplikację na mniejsze. Każdy komponent może mieć konkretną odpowiedzialność (np. formularz do dodania zadania, lista zadań).
- Jasny podział ról – jeśli jeden komponent służy do dodawania rekordów (formularz), a drugi do ich wyświetlania, możesz łatwo zarządzać stanem poprzez emitowanie zdarzeń.
- Rozważaj emitowanie zdarzeń tylko w momentach kluczowych – np. gdy dane zostaną zapisane w bazie, a nie przy każdej drobnej zmianie, by uniknąć nadmiernej liczby interakcji.
Ćwiczenia
W ramach ćwiczeń zbudujmy dwa komponenty:
TaskCreate– komponent odpowiedzialny za dodawanie nowego zadania.TaskList– komponent odpowiedzialny za wyświetlanie listy zadań i ewentualne dodatkowe operacje na nich (CRUD).
Ćwiczenie 1. Komponent TaskCreate
Generowanie komponentu
Wykorzystujemy Artisan:
php artisan make:livewire TaskCreate
Implementacja logiki dodawania zadania
Załóżmy, że mamy model Task z polami name oraz status. Komponent TaskCreate będzie zawierał formularz do dodania nowego zadania:
'required|min:3',
'status' => 'required',
];
public function render()
{
return view('livewire.task-create');
}
public function createTask()
{
// Walidacja danych
$this->validate();
// Zapis do bazy
Task::create([
'name' => $this->name,
'status' => $this->status,
]);
// Resetowanie pól formularza
$this->reset(['name', 'status']);
// Wyemitowanie zdarzenia do innych komponentów
$this->emit('zadanieUtworzone');
// (Opcjonalnie) Wysłanie zdarzenia do przeglądarki
$this->dispatchBrowserEvent('zadanie-utworzone', [
'message' => 'Nowe zadanie zostało pomyślnie dodane!'
]);
}
}
Widok task-create.blade.php
Dodaj nowe zadanie
W momencie kliknięcia przycisku „Dodaj zadanie” Livewire wywołuje metodę createTask(). Po pomyślnym dodaniu zadania do bazy następuje emit('zadanieUtworzone'), które może przechwycić inny komponent – w naszym przypadku będzie to TaskList.
Ćwiczenie 2: Komponent TaskList
Generowanie komponentu
php artisan make:livewire TaskList
Implementacja logiki wyświetlania i obsługa eventu
W komponencie TaskList odbieramy zdarzenie zadanieUtworzone i odświeżamy listę zadań:
'odswiezListeZadan'
];
public function render()
{
return view('livewire.task-list', [
'tasks' => $this->pobierzListeZadan()
]);
}
// Metoda wywoływana po otrzymaniu eventu
public function odswiezListeZadan()
{
// Możemy np. zresetować paginację, by wrócić na pierwszą stronę
$this->resetPage();
}
protected function pobierzListeZadan()
{
return Task::orderBy('id', 'desc')->paginate(10);
}
}
Zwróć uwagę, że w $listeners definiujemy parę klucz-wartość, gdzie kluczem jest nazwa zdarzenia, a wartością nazwa metody, która ma zostać wywołana po nadejściu zdarzenia. W tym przypadku jest to odswiezListeZadan.
Widok task-list.blade.php
Lista zadań
@foreach($tasks as $task)
-
{{ $task->name }} - {{ $task->status }}
@endforeach
{{ $tasks->links() }}
Teraz, gdy w komponencie TaskCreate dodamy nowe zadanie, zdarzenie zadanieUtworzone zostanie wyemitowane i TaskList odbierze je, po czym wywoła metodę odswiezListeZadan(). Ta metoda może zresetować paginację i w efekcie spowoduje ponowne wyrenderowanie listy w widoku.
Ćwiczenie 3: (Opcjonalnie) Notyfikacje w przeglądarce
W kodzie TaskCreate widzimy przykład użycia dispatchBrowserEvent():
$this->dispatchBrowserEvent('zadanie-utworzone', [
'message' => 'Nowe zadanie zostało pomyślnie dodane!'
]);
W widoku Blade możemy nasłuchiwać na takie zdarzenie za pomocą JS. Na przykład, jeśli używamy Alpine.js, możemy umieścić coś takiego:
...
Po tym wydarzeniu w przeglądarce zostanie wyświetlone powiadomienie typu alert z treścią: „Nowe zadanie zostało pomyślnie dodane!”.
Podsumowanie
Mechanizm zdarzeń w Livewire jest kluczowy dla tworzenia bardziej rozbudowanych aplikacji, w których wiele komponentów musi ze sobą współpracować. Główne punkty, na które warto zwrócić uwagę:
- Eventy –
emit()orazemitTo()to proste, a jednocześnie bardzo potężne narzędzia do komunikacji pomiędzy komponentami. - Listeners –
$listenersw komponencie pozwala na reakcję na określone zdarzenia – wystarczy przypisać nazwę zdarzenia do metody. - Struktura aplikacji – warto dzielić aplikację na mniejsze komponenty (np.
TaskCreate,TaskList), a następnie łączyć je za pomocą zdarzeń. - dispatchBrowserEvent – umożliwia komunikację z samą przeglądarką, co pozwala na wykorzystanie natywnych funkcjonalności, takich jak
alert()czy animacje w JS/Alpine.js.
Dzięki eventom możemy łatwo tworzyć dynamiczne interfejsy – np. po dodaniu zadania w jednym komponencie, inny odświeży się automatycznie i pokaże nowe dane. To kolejny krok w kierunku budowania złożonych, a jednocześnie intuicyjnych aplikacji w ekosystemie Laravel + Livewire.