Как запретить использование параметра при предварительном нажатии в Livewire

#laravel #laravel-livewire

#laravel #laravel-livewire

Вопрос:

Этот код является частью файла представления, связанного с компонентом Livewire.

Как предотвратить использование параметра перед нажатием кнопки?

Вид

     ...
        @foreach ($babies as $baby)
    ...
                <div
                    class="flex justify-between w-11-12 py-1  mb-1 ml-2 leading-6 text-sm font-medium ext-left text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-blue-800 focus:outline-none">
                    <button wire:click="setAte({{ $baby, $ate = 0 }})"
                        class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-ring-600 {{ $baby['ate'] == 0 ? "bg-blue-500" : "bg-red-500"   }}">
                        S</button>
                    <button wire:click="setAte({{ $baby, $ate = 1 }})"
                        class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 1 ? "bg-blue-500" : "bg-red-500"}}">
                        M</button>
                    <button wire:click="setAte({{ $baby, $ate = 2}})"
                        class="flex w-1-3 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 2 ? "bg-blue-500" : "bg-red-500"  }}">
                        L</button>
                    <div>{{ $baby['ate'] }}</div> {{-- <---check code --}}
                </div>
    @endforeach
    ...
 

Компонент

 public function setAte($baby, $ate)
{
    $baby['ate'] = $ate;
    $selectedBaby = Baby::find($baby['id']);
    $selectedBaby->save();
}
 

Ошибка

Исключение IlluminateContractsContainerBindingResolutionException Не удается разрешить зависимость [Параметр #1 [ $ate ]] в классе App Http LivewireClassroom BabyStatus

введите описание изображения здесь

Решение 1

//Компонент

 public $baby;

protected $rules = [
    'baby.ate' => 'required|int|min:0|max:2'
];

public function updateAte($ate)
{
    $this->baby->ate = $ate;
    $this->baby->save();
}
 

//Просмотр

 <button wire:model="baby" wire:click="updateAte(0)"
    class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-ring-600 {{ $baby['ate'] == 0 ? "bg-blue-500" : "bg-red-500"}}">S</button>
<button wire:model="baby" wire:click="updateAte(1)"
    class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 1 ? "bg-blue-500" : "bg-red-500"}}">M</button>
<button wire:model="baby" wire:click="updateAte(2)"
    class="flex w-1-3 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 2 ? "bg-blue-500" : "bg-red-500"  }}">L</button>
 

Вот и все, спасибо @Unflux.

Ответ №1:

Я был бы склонен реорганизовать то, что у вас есть, и сделать каждый baby отдельный livewire component .

AppHttpLivewireBaby.php

 class Baby extends Component
{
    // your instance of a baby
    public $baby;

    // required to allow updating of the baby properties
    protected $rules = [
        'baby.ate' => 'required|int|min:0|max:2'
    ];

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

    // you can set the value of properties here if you want
    public function mount()
    {
        // for example:
        //$this->baby->ate = -100;
    }

    // when the value of ate is updated from the view
    // update the baby model
    public function updatedBaby()
    {
        $this->baby->save();
    }
}
 

resouresviewslivewirebaby.blade.php

 <div class="p-4 m-4">
    <h4>Baby Component - ate: {{ $baby->ate }}</h4>
    <div class="flex justify-between p-4 m-4">
        <button wire:click="$set('baby.ate', 0)"
                class="text-white px-2 rounded {{ $baby->ate === 0 ? "bg-blue-500" : "bg-red-500" }}">S
        </button>
        <button wire:click="$set('baby.ate', 1)"
                class="text-white px-2 rounded {{ $baby->ate === 1 ? "bg-blue-500" : "bg-red-500" }}">M
        </button>
        <button wire:click="$set('baby.ate', 2)"
                class="text-white px-2 rounded {{ $baby->ate === 2 ? "bg-blue-500" : "bg-red-500" }}">L
        </button>
    </div>
</div>
 

Примечание: использование === в приведенном выше. Предотвращает null неправильное определение или аналогичных значений как равных 0 .

Затем в вашем view :

 @foreach($babies as $baby)
  @livewire("baby", ["baby" => $baby]) // render your single baby component
@endforeach
 

Комментарии:

1. спасибо, но он не смог повторно выполнить обновление $baby['ate' ] в дочернем компоненте.

2. @JsWizard Что это $baby , массив или модель?

3. Теперь он также работает в дочернем компоненте, но возникла новая проблема, связанная с проблемой повторного отображения. Я думаю, что обновленные $baby данные должны передаваться родительскому компоненту, верно?

4. Если вы используете обновленную $baby модель в своем родительском компоненте, тогда да, вам нужно будет сообщить об этом родителю. Если ваш родитель просто перебирает $babies коллекцию и ничего больше не делает, я бы удалил его и просто использовал обычный блейд @foreach , как в моем примере.

5. Я решил это с помощью return redirect()->to('/child-component'); метода in the end of there update, но теперь это элегантный способ.