Почему метод компонента AppHeader не запускается при выделении?

#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 :

  1. 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…

  1. 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, я вижу мигающие данные на своей странице, и все данные исчезли. Это выглядит так :

    1. 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

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