AlpineJS catch child component value if set

Viewed 428

I am using AlpineJS and x-model, which works great in the following case:

<script src="https://unpkg.com/alpinejs@3.9.5/dist/cdn.min.js"></script>
<form x-data="{ value: '' }">
  <input x-model="value" placeholder="Type and see..." />
  <br>Value: <span x-text="value"></span>
</form>

But when I have nested components with the same property name, the value doesn't propagate to the parent component, it stays in the child component:

<script src="https://unpkg.com/alpinejs@3.9.5/dist/cdn.min.js"></script>
<form x-data="{ value: '' }">
  <div x-data="{ value: '' }">
    <input x-model="value" placeholder="Type and see..."/>
    <br>Child value: <span x-text="value"></span>
  </div>
  Parent value: <span x-text="value"></span>
</form>

I know this is a very specific case. One could say: "just make everything be one component". But I cannot do that, because the nested component will be a low level generic component that I need to reuse. And I need the parent to be able to access the same value attached to the model.

Any idea on how I can approach this without using $store?

1 Answers

You can use the x-modelable directive that can expose any Alpine.js property as a target of x-model directive. The child component's property name must be unique. The property name in x-model on the child component should be a parameter of a backend template system' macro function.

<script src="https://unpkg.com/alpinejs@3.9.5/dist/cdn.min.js"></script>
<form x-data="{ value: '' }">
  <div x-data="{ innerValue: '' }" x-modelable="innerValue" x-model="value">
    <input x-model="innerValue" placeholder="Type and see..." />
    <br>Child value: <span x-text="innerValue"></span>
  </div>
  Parent value: <span x-text="value"></span>
</form>

Related