【问题标题】:Dispatching browser event with property alpine js and livewire使用属性 alpine js 和 livewire 调度浏览器事件
【发布时间】:2021-12-07 01:21:32
【问题描述】:

我正在尝试在使用 alpine 和 livewire 在浏览器上调度事件时传递参数

在第一次尝试时,结果是我所期望的,id 与我通过的属性匹配:

但在第二次尝试时,发生了奇怪的事情,id 与我传递的属性不匹配:

我传递参数的刀片视图:

<div>
    <div class="card">
        <div class="d-flex justify-content-between align-items-center card-header">
          Todo List
          <livewire:todos.todo-add />
        </div>
        <ul class="list-group list-group-flush">
            @forelse ($todos as $todo)    
                <li class="list-group-item d-flex justify-content-between">
                    {{ $todo->title }}
                    <div x-data>
                        <button
                            class="btn btn-success"
                            @click.prevent="$dispatch('toast-confirmation', {
                                id: {{ $todo->id }},
                                action: 'complete',
                                message: 'Are you sure to complete this task ?'
                            })">Complete</button>
                        <button
                            class="btn btn-danger"
                            @click.prevent="$dispatch('alert-confirmation', {
                                id: {{ $todo->id }},
                                action: 'delete',
                                message: 'Are you sure to delete this task ?'
                            })">Delete</button>
                    </div>
                </li>
            @empty
                No data.
            @endforelse
        </ul>
    </div>
    <div class="d-flex justify-content-end mt-3">
        {{ $todos->links() }}
    </div>

    <x-alerts />
    <x-toasters />
</div>

TodoIndex livewire 类:

class TodoIndex extends Component
{
    use WithPagination;

    protected $paginationTheme = 'bootstrap';
    
    protected $listeners = [
        'todoAdded' => '$refresh',
        'complete',
        'delete',
    ];

    public function complete(Todo $todo)
    {
        $todo->update();

        $this->dispatchBrowserEvent('toast', [
            'type' => 'success',
            'message' => 'Task has been completed'
        ]);
    }
    
    public function delete(Todo $todo)
    {
        $todo->delete();

        $this->dispatchBrowserEvent('toast', [
            'type' => 'success',
            'message' => 'Task has been deleted'
        ]);
    }

    public function render()
    {
        return view('livewire.todos.todo-index', [
            'todos' => Todo::latest()->paginate(5)
        ]);
    }
}

警报(laravel 组件):

<div>
    @push('alerts')
        <script>
            // Alert Confirmation
            window.addEventListener('alert-confirmation', event => {
                Swal.fire({
                    title: 'Are you sure to delete this id : ' + event.detail.id + '?',
                    text: "You won't be able to revert this!",
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonColor: '#3085d6',
                    cancelButtonColor: '#d33',
                    confirmButtonText: 'Yes, delete it!'
                }).then((result) => {
                    if (result.isConfirmed) {
                        Livewire.emit(event.detail.action, event.detail.id)
                    }
                })
            })

            // Alert Info
            window.addEventListener('alert-info', event => {
                Swal.fire({
                    icon: event.detail.icon,
                    title: 'Oops...',
                    text: 'Something went wrong!'
                })
            })
        </script>
    @endpush
</div>

app.layouts(laravel 组件):

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

        <title>Hello, world!</title>

        <link rel="stylesheet" href="/css/style.css">
    
        @livewireStyles
        
        <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
    </head>
    <body>
        <x-navbar />
        
        <div class="container py-4">
            {{ $slot }}
        </div>


        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
        
        {{-- SweetAlert2 --}}
        <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>

        {{-- Toastr --}}
        <script src="/js/cute-alert/cute-alert.js"></script>
        
        @stack('alerts')

        @stack('toasters')

        @livewireScripts
    </body>
</html>

知道如何解决这个问题吗?

【问题讨论】:

    标签: laravel-livewire alpine.js


    【解决方案1】:

    从 discord 得到答案,感谢 Josh Hansley 先生 实际上它在文档中也提到了Dom Diffing Issue

    在我的情况下,解决方案是像这样添加 wire:key="todo-{{ $todo->id }} :

    <li class="list-group-item d-flex justify-content-between" wire:key="todo-{{ $todo->id }}">
    
        {{ $todo->title }}
    
        <div x-data>
    
            <button
                class="btn btn-success"
                @click.prevent="$dispatch('toast-confirmation', {
                    id: {{ $todo->id }},
                    action: 'complete',
                    message: 'Are you sure to complete this task ?'
                })">Complete</button>
            <button
                class="btn btn-danger"
                @click.prevent="$dispatch('alert-confirmation', {
                    id: {{ $todo->id }},
                    action: 'delete',
                    message: 'Are you sure to delete this task ?'
                })">Delete</button>
    
        </div>
    </li>
    

    添加“todo-”前缀是最佳实践,以避免发生一些奇怪的形态错误

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      • 2021-05-13
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多