为什么不触发 livewire 发出的事件?

Why emitted events of livewire is not triggered?

在laravel 7学习livewire/livewire1.3我遇到了emitd 事件并不总是被触发

我用命令创建了组件

php artisan make:livewire hostel/hostelsHomepageSpotlight

并简化代码我没有看到事件警报。 在 app/Http/Livewire/Hostel/HostelsHomepageSpotlight.php 中:

<?php

namespace App\Http\Livewire\Hostel;

use Auth;
use DB;
use App\Config;

use App\Hostel;
use App\HostelImage;
use App\library\CheckValueType;
use App\Settings;
use Livewire\Component;

class HostelsHomepageSpotlight extends Component
{

    public function render()
    {

        $hostels     = [];
        $current_page= 1;
        $hostel_rows_count = Hostel
            ::getByStatus('A')
            ->count();

        $this->emit('hostelsHomepageSpotlightOpened', [ 'mode'=> 'hostels_homepage_spotlight', 'current_page'=>$current_page, 'hostel_rows_count'=>$hostel_rows_count ] ); // EMIT EVENT

        return view('livewire.hostel.hostels-homepage-spotlight', [
            'hostelsDataRows' => $hostels,
            'hostel_rows_count'=> $hostel_rows_count,
            'current_page'=> $current_page,
        ]);
    }
}

并在 resources/views/livewire/hostel/hostels-homepage-spotlight.blade.php:

<div>
    
    <h1>hostelsHomepageSpotlightOpened</h1>

</div>   

<script>
    // If to uncomment line below I see  alert
    // alert( 'resources/views/livewire/hostel/hostels-homepage-spotlight.blade.php::' )
    window.livewire.on('hostelsHomepageSpotlightOpened', data => {
        // I DO NOT SEE ALERT BELOW ANYWAY
        alert( 'hostelsHomepageSpotlightOpened::' )
        console.log('facility_opened data::')
        console.log(data)
        // alertsInit(data.mode)
        // lazyImagesInit("img.lazy_image")
    })
</script>

为什么没有触发事件?有没有办法调试它?

更新#2: 我知道关于包装 div 的规则(没有任何 class 或样式定义)。 我还要删除 JS 代码吗?

我试图移动 resources/js/app.js 中的所有 JS 代码:

window.$ = window.jQuery = require('jquery');

require('./bootstrap');

var Turbolinks = require("turbolinks")
Turbolinks.start()

// If to uncomment the line below I see it
// alert( '::resources/js/app.js' )
window.livewire.on('hostelsHomepageSpotlightOpened', data => {
// I do not see this alert
    alert( 'hostelsHomepageSpotlightOpened::' )
    console.log('facility_opened data::')
    console.log(data)
    // alertsInit(data.mode)
    // lazyImagesInit("img.lazy_image")
})

在我的 resources/views/layouts/app.blade.php 中:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" xmlns:livewire="http://www.w3.org/1999/html">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Laravel:Livewire</title>
    
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    
    <link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet" type="text/css">
    <link rel="icon" type="image/png" href="/favicon.ico"/>
    
    
    <link href="/css/app.css" rel="stylesheet">
    
    <script src="{{ asset('js/lazyload.js') }}"></script>   
    
    <!-- Styles -->
    @livewireStyles
    @livewireScripts
    
    <script src="{{ asset('/js/app.js') }}"></script>
    <script src="{{ asset('/js/app/app_funcs.js') }}"></script>

</head>
<body class="text-center">

<div class="flexbox-parent page_container " id="page_content">
    <header class="flexbox-item header">
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
               ...
            </nav>

    </header>
    
    <main class="flexbox-item fill-area content flexbox-item-grow">
        @yield('content')
    </main>
    
    <footer class="flexbox-item footer  ml-3 mr-3">
        ...
        <p class="m-2">copyright_text</p>
    </footer>

</div>

</body>
</html>

而且我的代码无论如何都不会触发! 我想我的应用程序的有效结构是 app.js AFTER @livewireStyles 和@livewireScripts

更新 # 3:

我试过了,还是不行。我有登录表单:

<article class="page_content_container">

   ...    
    <form class="form-login" wire:submit.prevent="submit">
        <input
            wire:model.lazy="form.email"
            name="email"
            id="email"
            class="form-control editable_field"
            placeholder="Your email address"
            autocomplete=off
        >
    </form>
   ...    
    
</article> <!-- page_content_container -->
{{--@push('scripts')--}}
    <script>
        $("#email").focus();
    </script>
{{--@endpush--}}

当@push/@endpush 在上面的行中被注释时,它工作正常并且焦点设置为电子邮件输入。 但是,如果取消注释这两行,则焦点未设置。

我修改了我的 resources/views/layouts/app.blade.php :

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Laravel:Livewire</title>
    
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    
    <link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet" type="text/css">
    <link rel="icon" type="image/png" href="/favicon.ico"/>
    
    
    <link href="/css/app.css" rel="stylesheet">
    
    
    <!-- Styles -->
    @livewireStyles
    

    <script src="{{ asset('/js/app.js') }}"></script>
    <script src="{{ asset('js/lazyload.js') }}"></script>
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
    
    @livewireScripts
    @stack('scripts')
    
    
    <script src="{{ asset('/js/app/app_funcs.js') }}"></script>

app.js - 首先是 bootstrap 和 jquery 包含在那里...

谢谢!

Livewire 需要由 div 元素包裹的组件。

样本:

你的内容...

我的意思是我不确定您是否可以在您的 Livewire blade 中包含 javascript。尝试将它移到您的 app.js 文件中,看看它是否有效,因为其余部分看起来不错。

我记得遇到麻烦只是因为 blade 的第一行是 html 评论,而不是

所以,总是,你的 livewire blade 的第一行必须是 < div>,最后一行

希望对您有所帮助!

如果你想在 livewire 下写脚本 blade 试试这个方法。在您的主布局中放在@livewireScripts

@stack('scripts')

现在您可以从 livewire blade 文件中将脚本推送到此堆栈中,如下所示:

@push('scripts')
<script>
// some js code 

</script>
@endpush

更新: 为什么在您的情况下它不起作用是有道理的。您不应该在 RENDER 函数 IFF 中发出事件,如果您想在即将呈现的同一视图中收听它。对于您的情况,简单来说,发射发生在视图加载之前,因此,当您的视图准备就绪时,听它会晚 'bit',你迷路了! :-)

解决方案:将 JS(window.livewire.on...)放在外面一步,以​​便在渲染中发出事件时它已经准备就绪。

简单来说,将JS代码放在父文件的scripts部分,你包含的文件如下

@livewire('hostel.hostels-homepage-spotlight')

P.S。当你处理 livewire 时,要监听一个事件或触发一个事件, 不要忘记将其包装在准备好的文档中,即

$( document ).ready(function() {
    livewire.emit('event_foo', 'foooo');
});

因此,您的 Spotlight 父页面应如下所示:

<script>
    $( document ).ready(function() {
        window.livewire.on('hostelsHomepageSpotlightOpened', data => {
            alert( 'hostelsHomepageSpotlightOpened::' )
            console.log('facility_opened data::')
            console.log(data)
        });
    });
</script>

干杯,