Laravel Livewire V3 HTML isn’t updating after change

  Kiến thức lập trình

I’m building some kinds of tag selection element for my Laravel 11 Livewire v3 project. A user can select models which are saved to a database and then click to remove them. When I click to add/remove new models, my HTML badges aren’t being updated. I need realtime HTML re-rendering based on the data from the database to ensure accuracy and reliability. What am I missing?

Here’s my HTML livewire component file:

<div x-data>
  <div class="cursor-pointer border border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-blue-500 dark:focus:border-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600 rounded-md shadow-sm min-h-10 w-ful gap-4l" wire:click="toggleVisibility" x-on:click.away="$wire.justClose()">
    @if (isset($selectedModels))
      @foreach ($selectedModels as $index => $model)
        <x-badge wire:click="removeModel('{{ $model['pivot']['id'] }}')" small class="bg-slate-100 text-slate-800 ml-2 z-10">
          {{ $model['name'] ?? '' }}
        </x-badge>
      @endforeach
    @endif
  </div>

  @if ($isOpen)
    <ul class="border-b border-l border-r border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-blue-500 dark:focus:border-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600 rounded-b-md shadow-sm w-full">
      @foreach ($selectableModels as $model)
        <li wire:click="addModel('{{ $model->id }}')" class="py-1 px-4 w-full cursor-pointer hover:bg-gray-100">
          {{ $model['name'] ?? 'not set' }}
        </li>
      @endforeach
    </ul>
  @endif
</div>

And the PHP class:

<?php

namespace AppLivewireComponents;

use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentCollection;
use AppModelsSite;
use AppModelsSiteable;
use LivewireComponent;

class ModelAssociation extends Component
{
    public Model $model;
    public Collection $selectableModels;
    public array $selectedModels;

    public bool $isOpen = false;

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

    public function updateModels()
    {
        $model = $this->model->load('sites');
        $exclude = $model->sites->pluck('id')->toArray();

        $this->selectedModels = $model->sites->toArray();
        $this->selectableModels = auth()->user()->sites()->whereNotIn('id', $exclude)->get();
    }

    public function toggleVisibility()
    {
        $this->isOpen = ! $this->isOpen;
    }

    public function justClose()
    {
        $this->isOpen = false;
    }

    public function addModel(string $siteId)
    {
        $modelClass = get_class($this->model);
        $target = $modelClass::with('sites')->find($this->model->id);

        Siteable::updateOrCreate([
            'site_id' => $siteId,
            'siteable_type' => get_class($target),
            'siteable_id' => $target->id
        ], []);

        // $this->selectedModels = collect($target?->sites ?? [])->toArray();

        $this->dispatch('siteable-added');
    }

    public function removeModel(string $siteableId)
    {
        $siteable = Siteable::find($siteableId);
        if ($siteable) $siteable->delete();

        $this->updateModels();
    }

    public function render()
    {
        return view('livewire.components.model-association');
    }
}

I’ve tried the $refresh with events, and tried moving the part that outputs the array into a method to call when adding / removing.

LEAVE A COMMENT