Атрибут Modelable
Атрибут #[Modelable] используется в дочерних компонентах Livewire
для создания двусторонней привязки между свойством дочернего компонента
и свойством родительского компонента.
Это позволяет изменять данные в родителе через дочерний компонент.
Атрибут применяется к публичному свойству класса компонента.
Значение свойства автоматически синхронизируется с родительским свойством.
Синтаксис
<?php
namespace AppLivewire;
use LivewireComponent;
use LivewireAttributesModelable;
class ChildComponent extends Component
{
#[Modelable]
public $propertyName;
public function render()
{
return view('livewire.child-component');
}
}
?>
В родительском компоненте свойство передаётся через атрибут
wire:model или как обычный параметр:
<livewire:child-component :$parentProperty />
Пример
Создадим родительский компонент с числовым свойством и дочерний компонент, который будет его изменять:
<?php
namespace AppLivewire;
use LivewireComponent;
class ParentComponent extends Component
{
public $num = 0;
public function render()
{
return view('livewire.parent-component');
}
}
?>
<?php
namespace AppLivewire;
use LivewireComponent;
use LivewireAttributesModelable;
class ChildComponent extends Component
{
#[Modelable]
public $num;
public function inc()
{
$this->num++;
}
public function render()
{
return view('livewire.child-component');
}
}
?>
<div>
<livewire:child-component :$num />
<p>Родитель: {{ $num }}</p>
</div>
<div>
<button wire:click="inc">Увеличить</button>
<p>Дочерний: {{ $num }}</p>
</div>
После нажатия на кнопку значение $num изменится
как в дочернем, так и в родительском компоненте.
Пример
Используем атрибут #[Modelable] с строковым свойством.
Дочерний компонент будет редактировать текст через поле ввода:
<?php
namespace AppLivewire;
use LivewireComponent;
class ParentComponent extends Component
{
public $text = 'abcde';
public function render()
{
return view('livewire.parent-component');
}
}
?>
<?php
namespace AppLivewire;
use LivewireComponent;
use LivewireAttributesModelable;
class ChildComponent extends Component
{
#[Modelable]
public $text;
public function render()
{
return view('livewire.child-component');
}
}
?>
<div>
<livewire:child-component :$text />
<p>Родитель: {{ $text }}</p>
</div>
<div>
<input type="text" wire:model="text">
<p>Дочерний: {{ $text }}</p>
</div>
При вводе текста в поле ввода значение $text
синхронизируется между компонентами.
Пример
Можно передать в дочерний компонент массив и изменять его элементы:
<?php
namespace AppLivewire;
use LivewireComponent;
class ParentComponent extends Component
{
public $arr = ['a', 'b', 'c', 'd', 'e'];
public function render()
{
return view('livewire.parent-component');
}
}
?>
<?php
namespace AppLivewire;
use LivewireComponent;
use LivewireAttributesModelable;
class ChildComponent extends Component
{
#[Modelable]
public $arr;
public function addElement()
{
$this->arr[] = 'new';
}
public function render()
{
return view('livewire.child-component');
}
}
?>
<div>
<livewire:child-component :$arr />
<p>Родитель: {{ implode(', ', $arr) }}</p>
</div>
<div>
<button wire:click="addElement">Добавить элемент</button>
<p>Дочерний: {{ implode(', ', $arr) }}</p>
</div>
После добавления элемента массив обновится в обоих компонентах.
Смотрите также
-
атрибут
#[Reactive],
который позволяет подписаться на изменения свойства -
атрибут
#[Locked],
который блокирует изменение свойства из вне -
атрибут
#[Url],
который синхронизирует свойство с параметром URL -
атрибут
#[Session],
который сохраняет свойство в сессии