#laravel-livewire
Вопрос:
В Laravel 8, livewire2 я создаю компонент заголовка , который вызываю resources/views/layouts/frontpage.blade.php :
</head>
<body class="flex flex-col min-h-screen">
<header>
@livewire('app-header', ['layout'=>'frontend'])
</header>
<main class="frontend_page_container_wrapper z-20 ">
{{ $slot }}
</main>
<footer class="bg-green" style="height: 138px !important;">
@livewire('frontend-footer')
</footer>
@stack('modals')
@livewireScripts
</body>
</html>
Чтобы обновить текущую информацию в заголовке при открытии новой страницы в любом компоненте, который я называю событием компонента AppHeader.
Как в app/Http/Livewire/Hostel/HostelsHomepageSpotlight.php :
<?php
namespace AppHttpLivewireHostel;
...
use LivewireComponent;
class HostelsHomepageSpotlight extends Component
{
...
public function render()
{
return view('livewire.hostel.hostels-homepage-spotlight', [
])->layout('layouts.frontpage');
} // public function render()
public function mount()
{
$this->hostelsDataRows = Hostel
::getByStatus('A')
...
->paginate($hostels_per_page);
...
Log::info( varDump(-1, ' -1 HostelsHomepageSpotlight before setCurrentPageProperties::') );
// $this->emitUp('setCurrentPageProperties', [ // IF TO UNCOMMENT THIS LINE - IT DOES NOT WORK
$this->emitTo('AppHeaderAppHeader','setCurrentPageProperties', [
'layout' => "frontend",
'icon' => 'hostel',
'additive_class' => '',
'title' => 'Spotlight hostels',
'trigger_js_event' => true,
'template_container_id' => "hostels_homepage_spotlight_page_container"
]);
} // public function mount()
...
и в app/Http/Livewire/AppHeader.php :
<?php
namespace AppHttpLivewire;
use LivewireComponent;
class AppHeader extends Component
{
...
protected $listeners = ['setCurrentPageProperties' => 'setCurrentPagePropertiesCallback'];
public function render()
{
return view('livewire.app-header', [])
->layout('layouts.') ;//. $this->layout;
}
public function mount(
...
) {
...
}
public function setCurrentPagePropertiesCallback($data)
{
Log::info(varDump($data, 'INSIDE -1 setCurrentPagePropertiesCallback $data::'));
if ( ! empty($data['layout'])) {
$this->layout = $data['layout'];
}
...
} // public function setCurrentPagePropertiesCallback($data)
}
When I open page with HostelsHomepageSpotlight.php component
I see degugging line
-1 HostelsHomepageSpotlight before setCurrentPageProperties
but not
INSIDE -1 setCurrentPagePropertiesCallback
as setCurrentPagePropertiesCallback method of HostelsHomepageSpotlight.php is not triggered.
How can it be fixed?
MODIFIED BLOCK :
- I had misspelling in name of target component. It is “AppHeader”, so fixing :
$this->emitTo('AppHeader','setCurrentPageProperties', [
this event is not triggered in app/Http/Livewire/AppHeader.php, with declared :
class AppHeader extends Component
{
...
protected $listeners = ['setCurrentPageProperties' => 'setCurrentPagePropertiesCallback'];
...
public function setCurrentPagePropertiesCallback($data)
{
Log::info(varDump($data, 'INSIDE -1 setCurrentPagePropertiesCallback $data::'));
...
}
}
I also tried :
$this->emit('setCurrentPageProperties', [
But it does not work anyway…
- In AppHeader Component resources/views/livewire/app-header.blade.php I added calling method of AppHeader Component as :
<a wire:click="appHeaderClickTest" class=" block text-sm px-2 py-4 hover:bg-green-500 transition duration-300 ">
Test2
</a>
with defintion in app/Http/Livewire/AppHeader.php :
public function appHeaderClickTest() {
Log::info( varDump(-12, ' -12 appHeaderClickTest::') );
}
and clicking on «Test2» button I see message in log file.
So I check that I put valid AppHeader Component and it works ok when I click «Test2» button
MODIFIED BLOCK # 2:
I created new livewire app EventsTest
with 4 components:
php artisan make:livewire Home
php artisan make:livewire hostel/HostelsHomepageSpotlight
php artisan make:livewire AppHeader
php artisan make:livewire hostel/HostelViewPage
and I placed HostelsHomepageSpotlight on home page.
In my app just 2 links and AppHeader at header of resources/views/layouts/app.blade.php
I emit event setCurrentPageProperties but it is not triggered in AppHeader (I have default title and no logs rows)
I uploaded it on https://github.com/sergeynilov/EventsTest
Could you please to look at it?
MODIFIED BLOCK # 3:
It works (I see valid title text) with setting
из корневого div шаблона HostelsHomepageSpotlight, но, как и в методе mount() HostelsHomepageSpotlight, я читаю все данные из БД, которые я показываю на странице HostelsHomepageSpotlight, я вижу мигающие данные на своей странице, и все данные исчезли. Это выглядит так :
-
- mount() method read all data on my of HostelsHomepageSpotlight
page 2) emitHeaderToComponent is called from template 3) method
emitHeaderToComponent inside of component is run and emiting
setCurrentPageProperties from header component 4) in heade component
title of header is assigned and I see it in header of my app
- mount() method read all data on my of HostelsHomepageSpotlight
But in one of 2-4 steps data I read on step 1 is cleared… Why and how can it be fixed?
MODIFIED BLOCK # 4 :
In component HostelsHomepageSpotlight.php I declared array and fill it in mount method :
<?php
namespace AppHttpLivewireHostel;
use LivewireComponent;
class HostelsHomepageSpotlight extends Component
{
private $hostelsDataRows = [];
public function render()
{
Log::info('-1 HostelsHomepageSpotlight ::' . print_r(-1, true));
return view('livewire.hostel.hostels-homepage-spotlight', [
'hostelsDataRows' => $this->hostelsDataRows,
]);
}
public function mount()
{
Log::info('-1 HostelsHomepageSpotlight MOUNT -99::' . print_r(-99, true));
$this->hostelsDataRows = [
['id' => 1, 'label 1'],
['id' => 2, 'label 2'],
];
}
public function emitHeaderToComponent()
{
/* $this->hostelsDataRows = [
['id' => 5, 'label 5'],
['id' => 6, 'label 6'],
];*/
$this->emit('setCurrentPageProperties', [
'title' => 'Cal from ' . __CLASS__,
]);
}
}
и отображение содержимого каталогов хостелей в resources/views/livewire/hostel/hostels-homepage-spotlight.blade.php
Я вижу, как данные мигают и исчезают с экрана.
Я смотрю, как этот компонент emitHeaderToComponent запускается после монтирования и очищает содержимое всех переменных так, как они объявлены в компоненте.
Если раскомментировать заполнение данных хостов в компоненте emitHeaderToComponent — эти данные видны на экране. Я думаю, что это может быть решением проблемы(загрузка всех данных компонентов в провод:init=»»), но не уверен, что это хорошее решение? Если это поведение/функция, описанные в документах?
Спасибо!
Комментарии:
1. Я думаю, что если вы обновите всю страницу, вы потеряете состояние. И именно по этой причине свойство title не обновляется в think
2. Вы можете использовать
wire:init
3. проверьте ответ
4. что вы имеете в виду шаг 1 данные очищены
5. пожалуйста, предоставьте репозиторий github с этой проблемой
Ответ №1:
Когда вся страница обновится, вы потеряете это состояние. Так вот почему события и слушатели не работают
Так что, как я и предлагал, вы можете использовать wire:init
в качестве обходного пути.
Добавьте приведенные ниже методы в оба HostelsHomepageSpotlight
HostelViewPage
компонента и.
public function emitHeaderToComponent()
{
$this->emit('setCurrentPageProperties', [
'title' => 'Cal from ' . __CLASS__,
]);
}
Теперь откройте представление для соответствующих компонентов hostels-homepage-spotlight
hostel-view-page
и добавьте следующее
<div wire:init="emitHeaderToComponent">
Your componenet based other stuff
</div>
Теперь попробуйте перейти по ссылке.
Я сделаю вилку репо и внесу изменения и предоставлю вам ссылку, чтобы она была более понятной
Представленный PR здесь
Комментарии:
1. Спасибо!. Пожалуйста, взгляните на ИЗМЕНЕННЫЙ БЛОК № 2