Laravel Livewire从数据库恢复数据而不是缓存

ryoqjall  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(109)

我有一个Laravel Livewire模型,它有两个公共属性:

  • 一个名为$tab的字符串(我用它在UI选项卡之间切换)
  • 一个名为$myobject的模型(带有关系)。

每当我检索我的$myobject模型时,我使用该高速缓存::remember函数从我的Redis缓存中检索我的模型,如果它在那里的话-这一切都在Livewire模型(mount)和我的Controller中完美地工作。
但是,如果我更改Livewire模型上的$tab属性(通过$emit或wire:click等),这将导致$myobject模型从数据库(而不是该高速缓存)中“再水合”,从而导致不必要的数据库查询(因为它已经在缓存中)。
我可以使用DebugBar看到这一点:

8 statements were executed, 6 of which were duplicated, 2 unique.
...
select * from `model` where `models`.`id` = 1 limit 1
350μs

/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php:108
...

字符串
我知道Livewire是“无状态”的,因此当任何事情发生变化时,需要将所有公共属性传递到浏览器/从浏览器传递...然而,有没有一种方法可以拦截再水合,这样我就可以从该高速缓存中生成我的$myobject(我很乐意编写这个函数),而不是执行昂贵的DB查询来检索它和它的关系?
SerializesAndRestoresModelIdentifiers.php脚本似乎是运行查询的罪魁祸首。
我真的不知道为什么它必须做这些查询,因为不是所有的数据都从浏览器返回吗?

swvgeqrz

swvgeqrz1#

你有没有考虑过尝试一下:

public function updatedTab($data) {
   // Here you can get the data from the cache and you provide data if you need to send something to the component class. - This fires every time tab changes value
}

字符串
Tbh这是我的方式,如果你需要运行mount并且它工作正常,那么我想你基本上可以用途:

public function updatedTab() {
   $this->mount();
}


这只是我的头上:)

roejwanj

roejwanj2#

有一个小的变通/黑客来实现这一点。任何public属性将被脱水和再水合每次请求来完整的循环。它必须执行查询才能获得模型,因为Livewire确实是无状态的。然而,protectedprivate属性没有水合。所以,你可以做的是:

class YourComponent Extends Component
{
    protected Model $yourModel;

    public function mount()
    {
        $this->getModel();
    }

    public function render()
    {
        return view('your-view', ['model' => $this->model]);
    }

    public function hydrate()
    {
        $this->getModel();
    }

    public function getModel()
    {
        $this->model = Cache::remember('yourKey', 100, function () {
            return Model::find(10);
        });
    }    
}

字符串
Hydrate在组件水合之后被调用,但在其他操作之前。这允许您重置模型字段,然后才能访问它。您必须在render方法中手动将其传递给视图,因为Livewire不会自动传递它。这样,您就可以从缓存中获取它,而不是让Livewire每次都查询数据库。

相关问题