【问题标题】:Laravel Livewire refreshing parent full-page componentLaravel Livewire 刷新父整页组件
【发布时间】:2022-02-25 06:49:07
【问题描述】:

我正在使用一个整页组件,其中包含一个处理模型更新的模态子组件。当用户点击 modal 上的保存并进行更新时,我想刷新父组件,这实际上是整个页面。但是,当我保存时,什么也没有发生。

这是我的父组件代码:

class LocationComponent extends Component
{
    public Location $location;
    public $client;
    public $legalEntities;
    public $smsTypes;
    public $clientContacts;
    public $locationContacts;

    protected $listeners = [
        'refreshParent' => '$refresh'
    ];

    public function mount()
    {
        $this->legalEntities = LegalEntityType::all();
        $this->smsTypes = SmsType::all();
        $this->roles = Role::all();
        $this->client = $this->location->client()->first();
        $this->clientContacts = $this->client->users()->get();
        $this->locationContacts = $this->location->users()->get();
    }

    public function render()
    {
        return view('livewire.locations.edit');
    }
}

这是子组件(模态):

class LocationEditModal extends Component
{

    public $states;
    public Location $location;

    protected $rules = [
       ...
    ];

    public function mount()
    {
        $this->states = USState::all();
    }


    public function render()
    {
        return view('livewire.location-edit-modal');
    }

    public function save()
    {
        $validatedData = $this->validate();
        $this->location->save($validatedData);
        $this->dispatchBrowserEvent('closeModal');
        $this->emit('refreshParent');

    }
}

我在我的父刀片文件中添加了这段代码,以查看事件是否正在触发,但似乎不是:

 <script>
      Livewire.on('refreshParent', event => {
          alert('the refreshParent event was fired');
      });
 </script>

这是我的网络路由文件中的路由:

  Route::get('/locations/{location}', [LocationComponent::class, '__invoke'])
        ->middleware('auth')
        ->name('locations.edit');

我也尝试将 $refresh 更改为 render,但这也没有用。

更新:

好的,在将我的事件侦听器脚本移动到我的主布局文件后,我现在收到了事件触发警报。仍然没有更新父组件,但它是一个开始。

更新 2:

我想知道这是否是我在父组件刀片视图中引用模型数据的方式。我只是按照我通常喜欢的方式引用它:

&lt;p class="d-flex" id="name"&gt;{{ $location-&gt;name }}&lt;/p&gt;

我不确定我的父组件是否可能没有得到更新的$location

更新 3:

根据我上次的更新,我想也许我需要刷新模型,所以我尝试将它添加到我的父组件挂载方法中,但它也不起作用:

$this-&gt;location-&gt;refresh();

不确定这是否相关,但在我的父组件中,它有 $location,它像这样调用子模态组件:

&lt;livewire:location-edit-modal :location="$location"/&gt;

再一次,只要把它放在那里,以防它有助于解决问题。我不知道我是否正在做某种无法正常工作的循环事情?在这一点上抓住稻草..

分辨率

好的,这可能对其他人没有帮助,但我使用的主题似乎有一些 Laravel 7 遗留的东西没有被删除(我认为)。根据关于升级 (https://laravel-livewire.com/docs/2.x/upgrading) 的 Livewire 文档,如果您使用的是 Laravel 版本 7,您应该从 RouteServiceProvider 中删除 -&gt;namespace($this-&gt;namespace) 行。版本 8 已将其删除。我以为我使用的是 Laravel 8,但也许对这个主题进行了升级,但从未被删除。

另一个问题是我在布局中使用了@yield('content'),这显然不再受支持。对于 livewire 版本 2,它应该使用 {{ $slot }} 语法。

【问题讨论】:

    标签: laravel laravel-8 laravel-livewire


    【解决方案1】:

    您在此处分享您的实际代码吗?我有点困惑,因为您的 LocationComponentLocationEditModal 组件实际上都没有将值设置为 $this-&gt;location

    无论哪种方式,都无需重新渲染整个LocationComponent modal,您只需将$this-&gt;location 刷新到位置的更新版本即可更新值。

    这样的事情应该可以工作:

    class LocationComponent extends Component {
    
      protected $listeners = [
        'locationUpdated'
      ];  
    
      public function locationUpdated()
      {
        $this->location->refresh();
      }
    }
    
    class LocationEditModal extends Component {
      public function save()
      {
        $this->emit('locationUpdated');  
      }
    }
    

    我不相信您分享的是实际代码,因此很难做出准确的推荐,但您的模态似乎根本不需要一个单独的组件。无论如何,您的 LocationComponent 已经被隔离到一个位置;我只想在LocationComponent 上直接保存/更新逻辑,而不是一个完整的单独组件。

    【讨论】:

    • 这是很好的反馈,谢谢。我现在正在尝试这个,是的,也许单独的位置模态组件是一个设计缺陷。我从模态开始修改 livewire,然后再没有回头思考我实际在做什么。
    • 就我的代码而言,我的理解(如果我错了,请纠正我)是路由模型绑定将允许 Livewire 知道您传递给 mount 方法的内容,您可以忽略它.这两种方法我都试过了,它们似乎都运行良好。
    猜你喜欢
    • 2021-05-11
    • 2021-02-14
    • 2021-04-16
    • 2021-03-31
    • 2020-06-09
    • 2021-05-12
    • 2022-08-17
    • 2022-06-11
    • 1970-01-01
    相关资源
    最近更新 更多