开发者问题收集

Laravel Livewire:未捕获的类型错误:无法读取 null 的属性(读取“代码”)

2024-02-26
492

为什么 $client 对象显然不为空时会出现此错误?

Blade

<div class="max-w-md mx-auto">
        <div class="bg-white shadow-md rounded px-4 pt-6 pb-4 mb-4">
        {{json_encode($client)}}
        <div class="mb-4">
            <label for="code" class="block text-gray-700 text-sm font-bold mb-2">Code:</label>
            <input type="text" wire:model="client.code" id="code" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
        <div class="mb-4">
            <label for="name" class="block text-gray-700 text-sm font-bold mb-2">Name:</label>
            <input type="text" wire:model="client.name" id="name" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
        <div class="mb-6">
            <label for="office_address" class="block text-gray-700 text-sm font-bold mb-2">Office Address:</label>
            <input type="text" wire:model="client.office_address" id="office_address" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
        <div class="flex items-center justify-between">
            <x-solid-button type="button" background="text-gray-900 bg-white border border-yellow-300 hover:bg-yellow-100 w-20" action="livewire" link="toggleEditMode"
                            component="">
                {{ $editMode ? 'Save' : 'Edit' }}
            </x-solid-button>
            @if ($editMode)
                <button wire:click="cancelEdit" class="bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
                    Cancel
                </button>
            @endif
        </div>
    </div>
    </div>

Livewire 组件

<?php

namespace App\Livewire\Clients;

use Livewire\Component;

class Details extends Component
{
    public object $client;
    public bool $editMode = false;

    public function mount($client)
    {
        $this->client = (object) $client;
    }

    public function toggleEditMode()
    {
        $this->editMode = !$this->editMode;
    }

    public function render()
    {
        return view('livewire.clients.details');
    }

    public function cancelEdit()
    {
        $this->editMode = false;
    }
}

当我使用 json_encode($client) 查看时,我正在获取页面上的客户端数据。但为什么我仍然收到错误。

我在互联网上找不到任何可靠的解决方案。我错过了什么?

我使用的是 livewire 版本 3.0

检查图片

3个回答

问题是 $client 已声明但未初始化。

第一个选项是将您的挂载更新为如下内容:

public function mount($client = null)
    {
        
        $clientArray = is_array($client) ? $client : [];
        $defaultClient = [
            'items' => $clientArray['name'] ?? '', 
            'code' => $clientArray['code'] ?? '', 
            'office_address' => $clientArray['office_address'] ?? '', 
        ];

        $this->client = (object) $defaultClient;
    }

或者分别声明每个元素:

在您的 Livewire 组件中:

...
public object $code;
public object $name;
public object $office_address;
...

在您的 Blade View 中:

...
        <div class="mb-4">
            <label for="code" class="block text-gray-700 text-sm font-bold mb-2">Code:</label>
            <input type="text" wire:model="code" id="code" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
        <div class="mb-4">
            <label for="name" class="block text-gray-700 text-sm font-bold mb-2">Name:</label>
            <input type="text" wire:model="name" id="name" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
        <div class="mb-6">
            <label for="office_address" class="block text-gray-700 text-sm font-bold mb-2">Office Address:</label>
            <input type="text" wire:model="office_address" id="office_address" class="appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" @unless($editMode) readonly @endunless>
        </div>
...
CloudTheWolf
2024-02-26

根据 文档 object 不直接支持作为属性。您还使用 wire:model 直接绑定到它。您是否尝试过将其存储为 array

Yinci
2024-02-28

我曾经使用过 livewire 的 Form Object,它当时工作正常。

使用

php artisan livewire:form ClientForm

创建表单类,这会在 Livewire->Forms 目录中创建一个客户端表单类...

我添加了验证规则和更新函数

<?php

namespace App\Livewire\Forms;

use App\Models\Clients;
use Illuminate\Validation\Rule;
use Livewire\Form;

class ClientForm extends Form
{
    public ?clients $client;

    public $code = '';
    public $name = '';
    public $office_address = '';

    public function rules()
    {
        return [
            'code' => [
                'required',
                Rule::unique('clients','code')->ignore($this->client),
            ],
            'name' => 'required',
            'office_address' => 'required'
        ];
    }

    public function setPost(Clients $client)
    {
        $this->client = $client;
        $this->code = $client->code;
        $this->name = $client->name;
        $this->office_address = $client->office_address;
    }

    public function store()
    {
        $this->validate();

        Clients::create($this->only(['code', 'name', 'office_address']));
    }

    public function update()
    {
        $this->validate();

        $this->client->update(
            $this->all()
        );

    }
}

这是我更新的 livewire 组件,我在其中调用了 ClientForm 类和更新函数。

<?php

namespace App\Livewire\Clients;

use App\Livewire\Forms\ClientForm;
use App\Models\Clients;
use Livewire\Component;

class Details extends Component
{
    public ClientForm $form;

    public object $client;
    public bool $isEditing = false;

    public function mount(Clients $client)
    {
        $this->form->setPost($client);
    }

    public function save()
    {
        $this->form->update();
        $this->isEditing = false; // Switch back to read-only mode
    }

    public function render()
    {
        return view('livewire.clients.details');
    }

}

更新的 blade 文件:

<div class="max-w-md mx-auto">
    <form wire:submit.prevent="save">
        @csrf
        <div class="bg-white shadow-md rounded px-4 pt-6 pb-4 mb-4">
            <div class="mb-4">
                <label for="code" class="block text-gray-700 text-sm font-bold mb-2">Code:</label>
                <input type="text" wire:model="form.code"
                       class="w-full px-3 py-2 border border-gray-300 rounded-md text-gray-700 {{$isEditing ? 'bg-white' :'bg-gray-200'}}"
                       @unless($isEditing) disabled @endunless
                >
                @error('form.code')
                <p class="text-red-500 text-xs italic">{{ $message }}</p>
                @enderror
            </div>
            <div class="mb-4">
                <label for="name" class="block text-gray-700 text-sm font-bold mb-2">Name:</label>
                <input type="text" wire:model="form.name" id="name"
                       class="w-full px-3 py-2 border border-gray-300 rounded-md text-gray-700 {{$isEditing ? 'bg-white' :'bg-gray-200'}}"
                       @unless($isEditing) disabled @endunless
                >
                @error('form.name')
                <p class="text-red-500 text-xs italic">{{ $message }}</p>
                @enderror
            </div>
            <div class="mb-6">
                <label for="office_address" class="block text-gray-700 text-sm font-bold mb-2">Office Address:</label>
                <input type="text" wire:model="form.office_address" id="office_address"
                       class="w-full px-3 py-2 border border-gray-300 rounded-md text-gray-700 {{$isEditing ? 'bg-white' :'bg-gray-200'}}"
                       @unless($isEditing) disabled @endunless
                >
                @error('form.office_address')
                <p class="text-red-500 text-xs italic">{{ $message }}</p>
                @enderror
            </div>
            <div class="flex items-center justify-around">
                @if ($isEditing)
                    <x-solid-button type="submit"
                                    background="text-gray-900 bg-white border {{$isEditing ?  'border-green-300 hover:bg-green-100' : 'border-yellow-300 hover:bg-yellow-100'}}   w-20"
                                    action="" link=""
                                    component="">
                        Save
                    </x-solid-button>
                    <x-solid-button type="button" background="bg-gray-500 hover:bg-gray-700 text-white w-20"
                                    action="livewire" link="$toggle('isEditing')"
                                    component="">
                        Cancel
                    </x-solid-button>
                @else
                    <x-solid-button type="button"
                                    background="text-gray-900 bg-white border border-yellow-300 hover:bg-yellow-100 w-20"
                                    action="livewire" link="$toggle('isEditing')"
                                    component="">
                         Edit
                    </x-solid-button>
                @endif
            </div>
        </div>
    </form>
</div>
mihir
2024-03-03