为什么Livewire 2组件调用自定义方法时itemDataRows列表为空?
问题原因
你遇到的问题由两个核心原因导致:
- 属性修饰符问题:
$itemDataRows被定义为private私有属性,Livewire只会在多轮请求之间持久化public属性的状态,私有/受保护属性不会保留上一次请求的赋值。 - Livewire执行顺序问题:当你点击全选按钮触发
selectAllItems动作时,Livewire的执行流程是:- 重新初始化组件类,所有属性恢复初始值(此时
$itemDataRows还是空数组) - 恢复上一轮请求的
public属性状态 - 先执行你调用的
selectAllItems方法,此时还没有运行render方法,$itemDataRows还没有被赋值 - 动作方法执行完成后,才会调用
render方法,此时才会给$itemDataRows赋值并传递给模板,因此模板可以正常渲染列表。
- 重新初始化组件类,所有属性恢复初始值(此时
模板中能正常获取$itemDataRows是因为你在render返回时将该变量传递给了视图,视图访问的是传递过去的局部变量,不是组件类的私有属性。
修复方案
建议将列表查询逻辑抽成独立的公共方法,避免代码重复,在render和selectAllItems中都调用该方法获取数据:
class CrudItems extends Component { public $selectedItems = []; // 不需要再将$itemDataRows定义为类属性,直接通过方法获取即可 ... // 抽离公共的列表查询方法 private function getItemList() { return Item::orderBy('created_at', 'desc') ->paginate($backend_per_page); } public function render() { $itemDataRows = $this->getItemList(); return view('livewire.admin.items.crud-items', [ 'itemDataRows' => $itemDataRows, 'item_rows_count' => $this->item_rows_count ])->layout('layouts.admin'); } public function selectAllItems() { $this->selectedItems = []; // 直接调用公共方法获取当前页的条目数据 foreach ($this->getItemList() as $item) { $this->selectedItems[$item->id] = true; } } public function calcSelectedItemsCount() { return count(array_filter($this->selectedItems)); } }
如果需要全选所有分页的所有条目,只需要修改getItemList方法为查询所有条目ID即可。
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

