【问题标题】:Laravel Livewire not persisting data in array when updatingLaravel Livewire 更新时不会将数据保存在数组中
【发布时间】:2021-09-14 18:58:40
【问题描述】:

我有一个名为public $items = [] 的属性。这可以有多个嵌套数组,即:$items.1, $items.2, $items.3 等等。这些子数组中的每一个都需要保存至少两条数据。

$items[1]['prop1'] = "value 1";
$items[1]['prop2'] = "value 2";
$items[2]['prop1'] = "value 1";
$items[2]['prop2'] = "value 2";

我的问题是,在我看来,我有两个输入绑定到这些子属性。

然后我根据这个输入添加一个新的数组条目。因此,如果用户在 prop1 中输入了某个东西,该数组将包含一个基于此输入的自动生成的元素。

现在问题来了。当我更改prop1 并在updatedItems 生命周期挂钩中捕获它时,它是正确的。但是当我更改prop2 时,它会覆盖prop1,并且该数组只保存一个值。

public function updatedItems($value, $nested)
{
    $nestedData = explode(".", $nested);
    // Get the nested property that was changed. this will yield a string formated as "1.prop1" or "2.prop1"
    // Let's pretend that the $value variable says "value 1" and the $nested variable is "1.prop1"
    if ($nestedData[1] == 'prop1') {
        $this->items[$nestedData[0]]["secondary_value"] = 'secondary value';
        // This should yield an items array that looks like this: items[1]['secondary_value'] = 'secondary value'
    }
    if ($nestedData[1] == 'prop2') {
        $this->items[$nestedData[0]]["third_value"] = 'third value';
        // This should yield an items array that looks like this: items[1]['third_value'] = 'secondary value'
    }
}

我的期望是我会得到一个如下所示的items 数组:

$items = [
    "1" =['prop1' => 'value 1', 'secondary_value' => 'secondary value'],
    "2" =['prop2' => 'value 1', 'third_value' => 'third value']
]

但无论我做什么,items 数组只保存一个值,即最近更改的值。因此,如果我先更改 prop1,然后更改 prop2,则数组将仅包含 prop2,并且不会附加到数组,而是基本上重新创建仅包含该值的整个数组。

我查看了多个其他问题,这些问题建议添加我已定义的 $rules 属性,但这仍然不能解决问题。我什至尝试过设置会话变量,但这似乎有同样的问题,每次都会被覆盖。 livewire 是否使用某种与 laravel 原生冲突的会话系统?任何有关使这些数据持久化以便我的数组可以同时保存 input1 和 input2 的值的帮助将不胜感激。

查看

<tr>
    <td colspan="5">
            <select wire:model="items.1.right_eye_brand">
            <option value=""></option>
            @foreach ($sortedItems as $o)
                <option value="{{ $o }}">{{ $o->brand }}</option>
            @endforeach
        </select>
    </td>
</tr>
<tr>
    <td colspan="5">
        <select wire:model="items.1.left_eye_brand">
            <option value=""></option>
            @foreach ($sortedItems as $o)
                <option value="{{ $o }}">{{ $o->brand }}</option>
            @endforeach
        </select>
    </td>
</tr>

【问题讨论】:

  • 根据您的输入,$nestedData[0] 始终等于 1,对吧?因此,您的预期数组将无法实现...
  • 还有一个循环也在进行,所以它不会总是“1”,例如我就是这样做的。主要问题是 items.1 将始终只保留一个属性,即使它有两个试图分配给它的关联键。
  • 你能包含你的组件视图吗?
  • 当然可以。我已经更新了我的问题。您可以看到我有两个选择,每个都绑定到 items.1,一个与右眼有关,一个与左眼有关。如果我更改任一选择,items.1 数组只包含那只眼睛。即使键不同,它也永远不会同时包含两者。
  • 我明白了。我会尝试重现错误。

标签: php laravel laravel-livewire


【解决方案1】:

问题似乎与 Livewire 生命周期有关。

问题

所以我能够使用 laravelplayground.com 重现该问题。这里:

reproduced error

简答

不要在updatedItems 中转储/dd。

长答案

事实上,items 在转储项目updatedItems 时是不正确的。但是,如果您在 render 方法中转储,items 应该是正确的。

我会深入研究以了解它发生的原因。但我猜想与在 updatedItems 方法中使用的原始 itemsitems 存在某种合并,并且合并发生在 update* 方法运行和调用 render 之前。

我在 laravel 操场上做了另一个例子,它在视图组件中显示项目内容,你可以看到返回的数据总是正确的。

final example

【讨论】:

  • 嗨,我想我遇到了一个类似的问题,这有点令人难以置信。您找到解决方案了吗?感谢您的研究!
  • 是的,我似乎生成了一个错误错误。正如这里的答案中提到的,该数组实际上是在保存,但是转储它给了我问题中描述的错误。因此,如果您将数组保存到数据库而不是 dd(),您应该会得到预期的结果。
猜你喜欢
  • 2015-10-31
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多