Tengo un modelo de prueba, con las inputs de atributo JSON, que es una matriz plana de cadenas (por ejemplo ['foo', 'bar', 'baz'] ).
Estoy tratando de vincular este campo a Livewire para poder tener un componente que permita al usuario agregar, modificar y eliminar elementos de esta matriz. Puedo hacer que funcione lo siguiente, donde cada entrada se completa automáticamente usando la matriz:
Para crear esto, utilizo el siguiente código (
<div class="test"> ... @php $index = 0; @endphp @foreach ($this->test->inputs as $input) @php $index ++; @endphp <div class="input-wrap"> <label>{{ $index }}</label> <input type="text" placeholder="input..." value="{{ $input }}"> <i class="fas fa-times"></i> </div> @endforeach ... </div> Sin embargo, estoy luchando por encontrar la mejor manera de vincular estos campos usando Livewire para que se sincronicen con el backend. Pensé en vincular un campo de entrada oculto con el json sin procesar, con algo de JS frontend para escuchar los cambios y mantenerse actualizado, pero cuando se trata de agregar un nuevo elemento, esto significará duplicar el div .input-wrap en el frente y backend, que se siente como un olor a código y sería más complicado de mantener.
¿Hay alguna manera de lograr esto sin depender en gran medida de JS front-end para la lógica de representación?
Si bien esta pregunta similar sugerida fue útil para darme la respuesta, no abordó del todo lo que buscaba. Para resolver esto, agregué los siguientes métodos a la clase del componente:
public function addInput() { $this->test->inputs->append(''); $this->test->save(); } public function removeInput($index) { $this->test->inputs->offsetUnset($index); $this->test->save(); } También agregué 'test.inputs.*' => 'string' a sus $reglas, y para permitir la modificación directa de la matriz, transmití las entradas a un objeto de matriz usando 'inputs' => AsArrayObject::class en la definición del modelo .
Luego, en la interfaz:
@foreach ($this->test->inputs as $input) <div class="input-wrap"> <label>{{ $index + 1 }}</label> <input wire:model="test.inputs.{{ $index }}"> <i wire:click="removeInput({{ $index }})" class="fas fa-times"></i> </div> @php $index ++; @endphp @endforeach