Ошибки Laravel Livewire не очищаются

Я экспериментирую с Laravel Livewire, и я столкнулся с ситуацией, когда предыдущие ошибки отображаются, даже если форма успешно отправлена.

Перед нажатием Сохранить

После нажатия Сохранить

HTML-сегмент name в файле лезвия customer-new.blade.php.

<div class="form-group">
    <div class="border rounded-0 px-1">
        <label class="mb-0" for="name">Name</label>
        <input wire:model="name" type="text" class="form-control form-control-sm " id="customer-name" aria-describedby="customer-nameHelp">
    </div>
    @error('name') <span class="err-message">{{ $message }}</span> @enderror
</div>

и код кнопки Сохранить:

<button 
  wire:click="store" 
  wire:loading.attr="disabled" 
  wire:target="store" 
  type="submit" 
  class="btn btn-sm btn-light">Save
</button>

store метод CustomerNew.php:

public function store()
{
    $this->validate([
        'name' => 'required|max:80',
        'street' => 'required|max:100',
        'city' => 'required|max:40',
        'dueAmount' => 'numeric|min:0'
    ]);

    Customer::create([
        'name' => $this->name,
        'street' => $this->street,
        'city' => $this->city,
        'due_amount' => $this->dueAmount,
    ]);

    session()->flash('message', 'Customer was saved');

    $this->clear();
}

и clear() метод похож на:

public function clear() {
  $this - > name = '';
  $this - > street = '';
  $this - > city = '';
  $this - > dueAmount = 0;
}

6 ответов

Согласно документам https://laravel-livewire.com/docs/input-validation,

Вам нужно сбросить проверки, когда захотите

Прямая обработка сообщений об ошибках. Методы validate() и validateOnly() должны обрабатывать большинство случаев, но иногда вам может потребоваться прямой контроль над внутренним ErrorBag Livewire.

Livewire предоставляет несколько методов для непосредственного управления ErrorBag.

Из любого места внутри класса компонента Livewire вы можете вызывать следующие методы:

    $this->addError('email', 'The email field is invalid.');
    // Quickly add a validation message to the error bag.
    
    $this->resetErrorBag();
    $this->resetValidation();
    // These two methods do the same thing. The clear the error bag.
    // If you only want to clear errors for one key, you can use:
    $this->resetValidation('email');
    $this->resetErrorBag('email');
    
    $errors = $this->getErrorBag();
    // This will give you full access to the error bag,
    // allowing you to do things like this:
    $errors->add('some-key', 'Some message');

ПОДСКАЗКА

Я использую методы сброса для функции гидратации, например следующие

...
    public function hydrate()
    {
        $this->resetErrorBag();
        $this->resetValidation();
    }
...

Лучше отправить$nameкresetValidationиresetErrorBug. Таким образом вы сбрасываете проверку только для полей обновления. Вот мой пример:

      
    public function updated($name, $value)
    {
        $this->resetValidation($name);
        $this->resetErrorBag($name);
    }

Вам следует сбросить общедоступные свойства с помощью livewire's resetметод. Удалите ваш$this->clear() определение метода и замените его следующим:

$this->reset('name', 'street', 'city', 'dueAmount');
            $this->resetErrorBag();

Просто добавьте это в свойclear()метод. Это сбросит сумку ошибок после каждого сохранения.

Добавить id в сообщение об ошибке div

@error('name') <span class="err-message" id="name-error">{{ $message }}</span> @enderror

@error('street') <span class="err-message" id="street-error">{{ $message }}</span> @enderror

@error('city') <span class="err-message" id="city-error">{{ $message }}</span> @enderror

@error('due_amount') <span class="err-message" id="due_amount-error">{{ $message }}</span> @enderror

Обычно использования упомянутых выше методов более чем достаточно, и они должны решить все ваши проблемы:

      $this->resetErrorBag();
$this->resetValidation();

Однако на практике эти ошибки могут не исчезнуть. В качестве альтернативного решения можно применить следующий подход:

  1. Добавьте прослушиватель событий:
      window.addEventListener('reset-error', event => {
    const paragraph = document.getElementById(event.detail.id += '-error');
    if (paragraph) {
        paragraph.textContent = '';
    }
});
  1. Отправка события браузера:
      $this->dispatchBrowserEvent('reset-error', ['id' => "sandbox"]);

На данный момент этого должно быть достаточно, но если у вас возникнут какие-либо проблемы или возникнут дополнительные вопросы, не стесняйтесь спрашивать.

Другие вопросы по тегам