Livewire数组输入实时求和问题:hours_count数组被意外重置
Livewire数组输入实时求和问题排查与解决
问题描述
我做了一个带hours数组输入框的表单,想要用户在各个hours输入框输入时长时,实时计算总和并显示在页面的div里。但现在的问题是,每次在另一个hours输入框输入内容时,$this->hours_count数组都会被重置/重新初始化。
表单调用store方法保存条目时,$this->hours_count显示是对的,但输入过程中不行。这感觉和Livewire的快速入门计数器示例一样简单,但我就是搞不懂。我知道Livewire里的属性和变量会被重新初始化,但文档说公共属性不会,求指点方向。——Patryk
现有代码
Livewire组件代码
public $hours = []; public $hours_count = []; protected function rules() { return [ 'hours.*.amount' => 'nullable|numeric|min:.25|max:16', ]; } public function updatedHours($field) { // 获取$this->hours的键/索引 $hours_index = substr($field,6, -7); $this->hours_count[$hours_index] = $this->hours[$hours_index]['amount']; }
Blade视图代码
<form wire:submit.prevent="Store"> <x-forms.row wire:model="hours.{{$index}}.amount"> </x-forms.row> </form> <!-- 用于显示$this->hours_count总和的div --> <div>总时长:<!-- 这里显示总和 --></div>
问题根源
你当前的写法仅更新当前输入框对应的hours_count索引项,但Livewire在每次请求后会重新序列化公共属性,未被本次请求更新的hours_count数组项会因为没有被传递回后端而丢失,导致数组被“重置”。
解决办法
最优方案:直接实时计算总和
不需要额外维护hours_count数组,通过计算属性直接从hours数组求和,既简洁又避免状态丢失:
- 修改Livewire组件,添加计算属性并移除冗余代码:
public $hours = []; protected function rules() { return [ 'hours.*.amount' => 'nullable|numeric|min:.25|max:16', ]; } // 新增计算属性,实时求和 public function getTotalHoursProperty() { return collect($this->hours)->sum(function ($hour) { return (float)($hour['amount'] ?? 0); }); }
- 在Blade视图中直接调用计算属性:
<form wire:submit.prevent="Store"> <x-forms.row wire:model="hours.{{$index}}.amount"> </x-forms.row> </form> <div>总时长:{{ $this->totalHours }}</div>
可选方案:保留hours_count数组
如果必须维护hours_count,每次更新时要合并原数组与新值,确保所有项都被保留:
public function updatedHours($field) { $hours_index = substr($field,6, -7); // 合并原数组与当前更新项,保留所有已有值 $this->hours_count = array_merge( $this->hours_count, [$hours_index => $this->hours[$hours_index]['amount'] ?? 0] ); }
但此方案可靠性不如直接计算,建议优先使用第一种方案。
内容的提问来源于stack exchange,提问作者dfeva
相关产品推荐
相关产品推荐

