Публічна властивість з об'єктом власного класу (DTO, value object) за замовчуванням не працює: Livewire не знає, як перетворити його на JSON і назад. Для цього є два механізми.
1. Wireable - простий спосіб для власних класів. Клас сам описує свою серіалізацію:
use Livewire\Wireable;
final class Address implements Wireable
{
public function __construct(
public string $city = '',
public string $street = '',
) {}
public function toLivewire(): array
{
return ['city' => $this->city, 'street' => $this->street];
}
public static function fromLivewire($value): static
{
return new static($value['city'], $value['street']);
}
}
public Address $address;
<input wire:model="address.city">
2. Синтезатор - для типів, які не можна змінити (класи з бібліотек) або коли потрібен повний контроль:
use Livewire\Mechanisms\HandleComponents\Synthesizers\Synth;
final class MoneySynth extends Synth
{
public static $key = 'money';
public static function match($target): bool
{
return $target instanceof Money;
}
public function dehydrate($target): array
{
return [['amount' => $target->amount, 'currency' => $target->currency], []];
}
public function hydrate($value): Money
{
return new Money($value['amount'], $value['currency']);
}
}
// AppServiceProvider::boot()
Livewire::propertySynthesizer(MoneySynth::class);
$key- позначка в знімку: значення зберігається кортежем[дані, { s: 'money' }];match()- чи підходить синтезатор для значення під час дегідрації;dehydrate()/hydrate()- перетворення в обидва боки;- методи
get()іset()- якщо на вкладені частини значення має працюватиwire:model(money.amount).
Так само влаштовані вбудовані типи: Stringable, моделі, колекції, дати, енуми - це синтезатори всередині Livewire.
Що враховувати:
- усе, що повертає
dehydrate/toLivewire, видно в браузері - не кладіть туди секретів; - гідровані дані - введення користувача: значення можна змінити в запиті, тож
fromLivewire/hydrateмають валідувати, а не довіряти; - розмір - великий об'єкт їде в кожному запиті й відповіді;
- часто простіше тримати примітиви (
$city,$street) і збирати об'єкт у методі - власний тип потрібен, коли він справді спрощує код.