【问题标题】:Why method of AppHeader component is not triggered on emit?为什么 AppHeader 组件的方法不会在发出时触发?
【发布时间】:2021-11-29 09:09:09
【问题描述】:

在 Laravel 8 中,livewire2 我制作了一个标题组件,我调用了它 资源/视图/布局/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 App\Http\Livewire\Hostel;

...
use Livewire\Component;

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 App\Http\Livewire;

use Livewire\Component;

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)
    
}

当我使用 HostelsHomepageSpotlight.php 组件打开页面时 我看到了调试线

-1 HostelsHomepageSpotlight before setCurrentPageProperties

但不是

INSIDE  -1  setCurrentPagePropertiesCallback 

因为没有触发 HostelsHomepageSpotlight.php 的 setCurrentPagePropertiesCallback 方法。

如何解决?

修改块:

  1. 我的目标组件名称拼写错误。它是“AppHeader”,所以修复:
            $this->emitTo('AppHeader','setCurrentPageProperties', [

此事件在 app/Http/Livewire/AppHeader.php 中未触发,声明为:

    class AppHeader extends Component
    {  
        ...
        protected $listeners = ['setCurrentPageProperties' => 'setCurrentPagePropertiesCallback'];
        ...
        public function setCurrentPagePropertiesCallback($data)
        {
            \Log::info(varDump($data, 'INSIDE  -1  setCurrentPagePropertiesCallback $data::'));
        ...
        }
    }        

我也试过了:

            $this->emit('setCurrentPageProperties', [

但它无论如何都不起作用......

  1. 在 AppHeader 组件 resources/views/livewire/app-header.blade.php 我添加了 AppHeader 组件的调用方法为:
    <a  wire:click="appHeaderClickTest"  class=" block text-sm px-2 py-4 hover:bg-green-500 transition duration-300 ">
       Test2
    </a>

在 app/Http/Livewire/AppHeader.php 中有定义:

    public function appHeaderClickTest() {
        \Log::info(  varDump(-12, ' -12 appHeaderClickTest::') );
    }

并单击“Test2”按钮,我在日志文件中看到了消息。 所以我检查我是否放置了有效的 AppHeader 组件,当我点击“Test2”按钮时它工作正常

修改版块 #2: 我创建了新的 livewire 应用程序 EventsTest

有 4 个组件:

php artisan make:livewire Home
php artisan make:livewire hostel/HostelsHomepageSpotlight
php artisan make:livewire AppHeader
php artisan make:livewire hostel/HostelViewPage

我将 HostelsHomepageSpotlight 放在主页上。 在我的应用程序中,资源/视图/布局/app.blade.php 的标题中只有 2 个链接和 AppHeader 我发出事件 setCurrentPageProperties 但它没有在 AppHeader 中触发(我有默认标题并且没有日志行)

我上传到https://github.com/sergeynilov/EventsTest 你能看一下吗?

修改块#3:

设置有效(我看到有效的标题文本)

来自 HostelsHomepageSpotlight 模板的根 div,但如 HostelsHomepageSpotlight 的 mount() 方法我从 db 中读取了我在 HostelsHomepageSpotlight 页面上显示的所有数据 我在我的页面上看到闪烁的数据,然后所有数据都消失了。看起来像 :
    1. mount() 方法读取我的 HostelsHomepageSpotlight 上的所有数据
      第 2 页)从模板调用 emitHeaderToComponent 3)方法
      组件内部的 emitHeaderToComponent 正在运行并正在发射
      标题组件中的 setCurrentPageProperties 4) 在标题组件中 标题的标题已分配,我在我的应用程序的标题中看到它

但是在 2-4 步中,我在第 1 步中读取的数据被清除...为什么以及如何修复?

修改块#4:

在组件 HostelsHomepageSpotlight.php 中,我声明了数组并将其填充到 mount 方法中:

<?php

namespace App\Http\Livewire\Hostel;

use Livewire\Component;

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 中显示 hostelsDataRows 的内容 我看到数据在屏幕上闪烁和分散。

我看起来像在挂载后触发了 emitHeaderToComponent 并清除了所有变量的内容,它们是如何声明的 在组件中。

如果取消注释在 emitHeaderToComponent 中填充 hostelsDataRows - 这些数据在屏幕上可见。 我认为这可能是问题的决定(在wire:init =“”中加载所有组件数据),但不确定是 好决定吗?如果文档中描述了此行为/功能?

谢谢!

【问题讨论】:

  • 我认为,如果您进行整页刷新,您将失去状态。这就是 title 属性在 think 中没有更新的原因
  • 你可以使用wire:init
  • 查看答案
  • 什么意思第1步数据被清除了
  • 请在github repo提供问题

标签: laravel-livewire


【解决方案1】:

当整个页面刷新时,您将失去状态。这就是 eventslisteners 不起作用的原因

因此,正如我建议的那样,您可以使用 wire:init 作为解决方法。

将以下方法添加到HostelsHomepageSpotlightHostelViewPage 组件中。

public function emitHeaderToComponent()
{
    $this->emit('setCurrentPageProperties', [
        'title' => 'Cal from ' . __CLASS__,
    ]);
}

现在打开各个组件hostels-homepage-spotlighthostel-view-page 的视图并添加以下内容

<div wire:init="emitHeaderToComponent">
Your  componenet based other stuff
</div>

现在尝试点击链接。

我将创建一个 fork 回购并进行更改并为您提供一个链接,以便更清楚

提交公关here

【讨论】:

  • 谢谢!。请看一下 MODIFIED BLOCK #2
猜你喜欢
  • 2018-08-12
  • 2013-06-20
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多