出现错误:"Typed property must not be accessed before initialization" - Laravel Livewire

4

描述

我正在为模型属性做类型提示并尝试删除邀请数据。下面是它抛回给我的错误信息。由于我无法发现缺少了什么,请帮我解决这个问题。

不得在初始化之前访问已声明类型的属性 App\Http\Livewire\Backend\UserManagement\FormComponent\InvitationManagementModal::$invitation

剥离、可复制的代码片段

  • Livewire\InvitationManagementModal.php
<?php

namespace App\Http\Livewire\Backend\UserManagement\FormComponent;

use Livewire\Component;

use Livewire\WithPagination;
use App\Http\Livewire\Backend\DataTable\WithCachedRows;

use App\Models\Invitation;

class InvitationManagementModal extends Component
{
    use WithPagination, WithCachedRows;
    
    public $showInvitationManagementModal = false;
    public Invitation $invitation;

    protected $listeners = ['manageInvitation'];

    public function manageInvitation()
    {
        $this->showInvitationManagementModal = true;
    }

    public function deleteInvitation(Invitation $invitation)
    {
        $this->invitation->delete();
    }

    public function getInvitationRowsProperty()
    {
        return $this->cache(function () {
            $invitations = Invitation::where('registered_at', null)->paginate(5);
            return $invitations;
        });
    }

    public function render()
    {
        return view('livewire.backend.user-management.form-component.invitation-management-modal', ['invitations' => $this->invitationRows]);
    }
}
  • livewire\invitation-management-modal.blade.php
<div>
    <x-modal.stacked wire:model.defer="showInvitationManagementModal" id="scroll-lock">
        <x-slot name="title">Manage Invitation</x-slot>
        <x-slot name="description">Manage all the invitations which are yet to be accepted.</x-slot>
        <x-slot name="content">
            <div class="p-8 space-y-4">
                <ul class="flex flex-col divide divide-y w-full bg-white rounded-lg shadow">
                    @forelse($invitations as $key => $invitation)
                        <li class="flex flex-row">
                            <div class="flex flex-1 items-center px-8 py-4">
                                <div class="flex-1 mr-16">
                                    <div class="text-sm dark:text-white">
                                        {{ $invitation->email }}
                                    </div>
                                </div>
                                <button wire:click="deleteInvitation" class="text-right flex justify-end">
                                    <x-icon.trash />
                                </button>
                            </div>
                        </li>
                    @empty
                    @endforelse
                </ul>
                <div>
                    {{ $invitations->links() }}
                </div>
            </div>
        </x-slot>
        <x-slot name="footer">
            <x-button.secondary wire:click.defer="$set('showInvitationManagementModal', false)">Cancel</x-button.secondary>
        </x-slot>
    </x-modal.stacked>
</div>

背景

  • Livewire 版本:2.3.5
  • Laravel 版本:8.20.1
  • Alpine 版本:2.8.0
  • 浏览器:Chrome
2个回答

3
其他答案在细节上都有一些需要注意的地方。你不必检查$invitation,因为类型提示Invitation会使Laravel使用Model-Route-Binding,它会获取相应的记录——或者如果未找到,则抛出HTTP 404状态代码。

其次,这是您目前看到的实际错误,因为您不需要对$this->invitation做任何事情,因为它没有设置。相反,您应该向该方法传递参数。

在Livewire中循环数据时,始终建议使用wire:key,以便Livewire可以跟踪循环中的每个记录。

因此,对于实际的删除方法,只需在输入变量上调用删除方法即可。

public function deleteInvitation(Invitation $invitation)
{
    $invitation->delete();
    // Emit an event to notify the user that the record was deleted
    // Refresh the parent component to remove the invitation from the list

}

针对您的刀片,请在循环中的第一个元素中添加wire:key,并将其ID传递给该方法。
(因此使用wire:click="deleteInvitation({{ $invitation->id }})"而不是wire:click="deleteInvitation")。

@forelse($invitations as $key => $invitation)
    <li class="flex flex-row" wire:key="invitation_{{ $invitation->id }}">
        <div class="flex flex-1 items-center px-8 py-4">
            <div class="flex-1 mr-16">
                <div class="text-sm dark:text-white">
                    {{ $invitation->email }}
                </div>
            </div>
            <button wire:click="deleteInvitation({{ $invitation->id }})" class="text-right flex justify-end">
                <x-icon.trash />
            </button>
        </div>
    </li>
@empty
@endforelse

这意味着,由于$invitation属性从未被使用,因此可以删除该类的声明,即在public $showInvitationManagementModal = false;之后的那一行。
public Invitation $invitation;

1
这是完美的,它按预期工作,非常感谢伙计! - ToxifiedHashkey

0

试试这个:

public function deleteInvitation(Invitation $invitation)
{
    $this->invitation = $invitation;
    $this->invitation->delete();
} 

如果$invitation变量已经变为null,它也会抛出一个错误。 - Azahar Alam
使用模型路由绑定,当未找到时,您要么得到404错误,要么得到实际的模型。因此,不需要检查它。 - Qirel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接