Livewireでモデルのプロパティを直接バインドする
Livewireでは、Eloquentモデルのプロパティを直接バインドできる。書き方はこんな感じ。
//コンポーネント
use App\User;
class UserForm extends Component
{
public User $user;
protected $rules = [
'user.name' => 'required|max:100',
'user.email' => 'required|email',
];
public function save()
{
$this->validate();
$this->user->save();
}
}
//View
<form wire:submit.prevent="save">
<input type="text" wire:model="user.name">
<input type="email" wire:model="user.email">
<button type="submit">Save</button>
</form>
Livewire3.0でハマる
ある日、新しいプロジェクトで同じようにやってみるとバインドがうまくいかない。
ブラウザのコンソールで確認すると以下のようにエラーが出ている。
livewire.js?id=XXXXXXXXX:XXX Uncaught TypeError: Cannot read properties of null (reading 'name')
自分の凡ミスを疑ってしまい、かなりハマる。
Livewire3.0での解消法
Livewireのアップグレードガイド見たらちゃんと書いてあったね。
解消方法は次のとおり。
-
まず以下のコマンドを叩く。
php artisan livewire:publish --config
-
config/livewire.phpが生成されるのを確認。
-
livewire.phpの以下をtrueに変更する。
'legacy_model_binding' => false,
これでとりあえず解決した!
アップグレードする時はちゃんとドキュメント読まなきゃね。(ある意味凡ミスよね。)
ちなみに今回このような仕様変更があったのは、どうも3から追加したフォームオブジェクトを推したいという意図がありそう。
2からの移行は一旦これでOKやけど、新機能のフォームオブジェクトを使うとプロパティやらバリデーション関連を別のクラスに分離できるというメリットもあるみたいなので、そっちを試してみるのもありかも!(こちらはやったらまた追記します。)
[追記]emitも使えなくなってる!
emit()
も使えなくなっていた。もちろんこれもLivewireのアップグレードガイドみたらちゃんと書いてる。
emit()
とdispatchBrowserEvent()
がdispatch()
という一つのメソッドに統合されたらしいので$this->emit('my-event')
みたいに書いていたところは、全部$this->dispatch('my-event')
のように書き換えないといけない。
プロパティの直接バインドは設定ファイルの項目を一つ変更するだけで解決できるけど、これの方が厄介。稼働中のLivewire2.x -> Livewire3アップグレードは慎重に検討した方がいいと思う。