Day 08 | 触发事件

昨天提到了互动事件(Action)基本上能解决大部分页面中互动的需求,但若要能够跨元件来进行互动,例如呼叫其他元件中的 Function 就要靠今天的 $emit 事件啦~

Emit 事件

不光是能够从 Template Blade 中使用,也能够从 Livewire 元件中的 Function 使用,甚至还能在 JavaScript 中呼叫使用。

在 Template Blade 使用

<button wire:click="$emit('postAdded')">

在 Livewire 元件中使用

$this->emit('postAdded');

在 JavaScript 中使用

<script>
    Livewire.emit('postAdded')
</script>

设置监听 - Event Listeners

不过在使用 emit 前必须先在各个有要用到的元件中先宣告监听才能够成功透过 $emit 呼叫该元件中的 Function。

注意: 这边是很多人常常忘记做的步骤而导致怎样都呼叫不到,且 emit 是全域呼叫并不会提示是否呼叫成功或是报错。

class Day8 extends Component
{
    ...
    
    protected $listeners = ['toggleTitle' => 'toggleTitle'];

    public function render()
    {
        return view('livewire.example.day8');
    }

    public function toggleTitle()
    {
        ...
    }
}

外面 $emit 的名称也可以跟实际函数名称的不一样,像是这边我这个元件中使用的是 setTitleVisible () 而外面一样透过 $emit('toggleTitle') 来呼叫。

protected $listeners = ['toggleTitle' => 'setTitleVisible'];

传递参数

要传递参数也是非常简单的事:

$this->emit('postAdded', $post->id);
   protected $listeners = ['postAdded'];
 
    public function postAdded($id)
    {
        ...
    }

范围 - Scoping Events

由於 $emit 的范围可涵盖至目前页面上所有的 Livewire,也能做全域呼叫使用,换句话说就是能触发不同 Livewire 元件中同名的 Function,可以参考 Github 上 Day8 的范例。但有时候并不需要呼叫到全部的元件,那这时候就有以下几种方法可以只呼叫特定元件中的 Function:

* 只呼叫父元件 emitUp

$this->emitUp('postAdded');
<button wire:click="$emitUp('postAdded')">

* 透过元件名称呼叫 emitTo

$this->emitTo('counter', 'postAdded');
<button wire:click="$emitTo('counter', 'postAdded')">

* 只呼叫自己本身 emitSelf

$this->emitSelf('postAdded');
<button wire:click="$emitSelf('postAdded')">

在 JavaScript 中监听事件

资料储存成功後,要在页面显示成功的讯息还是需要透过 JS 来执行,毕竟那些放在按钮中的 wire:click() 事件没办法回传值,也没办法在 PHP 呼叫 JS 的 Function。那就只能够过这个方法来做产生操作回馈。

因此我们可以在 bladescript 区块中建立一个监听器,并透过 alert 来显示操作成功的讯息:

<script>
Livewire.on('postAdded', () => {
    alert('文章已经发布罗!');
})
</script>

之後的 $emit('postAdded') 也会触发上面的 JS 区块罗 ~

注意:这里的 <script> 必须放在 Layout 的页面才会生效,或者使用 @stack('scripts')@push('scripts') 来将 JS 的部分塞回 Layout 中才会生效,程序码可以参考我的 Day8 示范。

*如果觉得复杂建议使用下方浏览器监听的方法,会简单很多!!

触发浏览器的监听事件

也可以直接触发浏览器的监听事件,但这边就要使用 dispatchBrowserEvent () 而不是 emit()

$this->dispatchBrowserEvent('postAdded');

blade 上则要用 window.addEventListener 来建立监听:

<script>
window.addEventListener('postAdded', () => {
    alert('文章已经发布罗!');
})
</script>

范例

GitHub 网址在这边

运行之後打开 http://127.0.0.1:8000/day8 就能看到今天的范例啦!

档案的话分别在:
app\Http\Livewire\Example\Day8.php
resources\views\livewire\example\day8.balde.php

今天的范例会演示:

  1. 透过 $emit 同时呼叫 Day8Day8Child 中的 toggleTitle()
  2. 透过 JavaScript 来接收 $emit 的事件。
  3. 透过 浏览器的监听器 来接收 dispatchBrowserEvent 事件。

<<:  新新新手阅读 Angular 文件 - Get data from a server(1) - Day10

>>:  Day10 HTML表单元素

[Day 11] Select 下拉

Day10 在许多登入画面会选择某些内容 像选择参观网站是否满18岁等等选项 所以可以用下拉选单来显...

Javascript档案中使用Django template 变数

在template中我们可以定义javascript变数为djagno变数,如下: <scri...

字串和物件的差异

今天会用两个例子来比较看看多个字串和一个物件多笔资料有什麽不同 第一个范例是在data中放「首页」、...

[第三天]从0开始的UnityAR手机游戏开发-如何开启专案和汇入Vuforia插件到Unity

在开启专案之前必须有Unity授权才能开启和运行专案,所以在开启专案之前会先来教大家如何取得授权。 ...

DAY12 如何使用样板

做完大概长这样,左边的图片就会是显示在line上面的样子,有兴趣可以自己摸索一下,这边还有一个重点是...