Livewire:嵌套组件在 parent class 而不是 child class 上调用 属性

Livewire: nested component is calling property on parent class instead of child class

我目前正在开发 Laravel 应用程序的一部分,该应用程序可以跟踪书籍的阅读进度。我正在使用 Livewire 并且有两个组件。主要组件是 BookManager class,当书籍更新或删除时,它会显示所有书籍和更新。

class BookManager extends Component
{
    public $name;
    public $books;

    protected $listeners = ['refreshBookManager' => '$render'];
    
    public function mount()
    {
        $this->books = Book::all();

    }
    
    public function render()
    {
        return view('livewire.book-manager');
    }
    
}

它遍历 blade-file 中的所有书籍并为每本书呈现一个 BookField 组件。

// livewire/book-manager.blade.php
<div>
    <table class="table table-striped">
        @foreach($books as $book)
            <livewire:book-field :book="$book" :key="$book->id" />
        @endforeach
    </table>
</div>

我认为每个 BookField 组件都可以跟踪自己的个人书籍,因此用户可以在此处单独更新每本书的进度或将书籍标记为已完成。

class BookField extends Component
{
    public $pages_read;
    public Book $book;

    public function render()
    {
        return view('livewire.book-field');
    }

    public function update()
    {
        //...
    }

    public function finish()
    {
        //...
    }

}
// livewire/book-field.blade.php
<div>
    <tr>
        <td>
            {{$book->name}}
        </td>
        <td>
            <progress value="{{ ($book->pages_read / $book->pages_total) * 100 }}" max="100"></progress>
        </td>
        <td>
            <input class="form-control" type="number" wire:model.defer="pages_read" placeholder="{{$book->pages_read}}">
        </td>
        <td>
            / {{$book->pages_total}}
        </td>
        <td width="15%">
            <button class="btn btn-primary" type="submit" wire:click="update()">Update</button>
            <button class="btn btn-success" type="submit" wire:click="finish()">Finish</button>
        </td>
    </tr>
</div>

我很难尝试让每个 BookField 正确绑定到它们的 Book 模型。单击更新按钮时出现的错误是:

Livewire\Exceptions\MethodNotFoundException
Unable to call component method. Public method [update] not found on component: [book-manager] 

我收到类似的属性错误:

Livewire\Exceptions\PropertyNotFoundException
Property [$pages_read] not found on component: [book-manager] 

所有 BookFields 都使用其特定 Book 模型的正确信息成功呈现。当我将 $book 变量转储到 BookField 组件中时,我得到了正确的 Book 实例及其所有属性和方法。

但出于某种原因,它似乎正在寻找 parent class 上的 $pages_read 属性 或 update() 或 finish() 方法它自己的 BookField 实例 class。我对 Livewire 没有足够的经验,不知道是什么导致了这个问题或如何解决它,所以如果有人能帮助我,我将不胜感激。

尝试使用 :wire:key 而不是 :key,此处:

而不是:

<livewire:book-field :book="$book" :key="$book->id" />

使用

<livewire:book-field :book="$book" :wire:key="$book->id" />

确保视图用 div TAG 包裹 组件的视图应该有标签 DIV

用 div 包裹 table 会导致此错误。

Livewire 要求您的 blade 模板有一个根, 因此,删除包装“div”标签并使用“tr”标签作为根修复它。

因此,您在 livewire/book-field.blade.php 上的代码应如下所示:

<tr>
    <td>
        {{$book->name}}
    </td>
    <td>
        <progress value="{{ ($book->pages_read / $book->pages_total) * 100 }}" max="100"></progress>
    </td>
    <td>
        <input class="form-control" type="number" wire:model.defer="pages_read" placeholder="{{$book->pages_read}}">
    </td>
    <td>
        / {{$book->pages_total}}
    </td>
    <td width="15%">
        <button class="btn btn-primary" type="submit" wire:click="update()">Update</button>
        <button class="btn btn-success" type="submit" wire:click="finish()">Finish</button>
    </td>
</tr>