Closed SimoTod closed 4 years ago
Not sure if it fits here but I think I need something similar.
I have a "modal component" (via Laravel components) that I want to have its "own scope"
// html
<div x-data="{ someParentVariable: 'lol' }>
<button @click="openModal('modal-1')">Open modal</button>
<div id="modal-1" x-data="modal()" x-init="init()">
<template x-if="$visible">
// make an ajax request and show the content here when $visible is true,
// this way it will only make the request when the modal is opened.
// If I want to access to "someParentVariable", it will be undefined
</template>
</div>
</div>
// modal component
function modal()
{
return {
$visible: false,
init() {
var id = this.$el.getAttribute('id');
// the "openModal" function fires this event
window.addEventListener(`modal:show ${id}`, () => {
this.$visible = true;
})
}
};
}
What should I do? Thanks.
Change openModal()
to take a second argument, which is someParentVariable
, send that as part of the event, and change the event listener to get that value from the event.
@carlmjohnson That's not the point.
"openModal" is a "global" function and maybe it's not the best example to explain what I want. This won't work neither (I guess it is in the comments too)
<div x-data="{ foo: 'bar' }">
<div x-data="{ baz: 'baz' }>
<span v-text="foo"></span> // foo is undefined
</div>
</div>
Lots of suggested solutions but this doesn't seem to have a solid solution and is closed? What's the status of this? In development? Shelved?
See https://github.com/alpinejs/alpine/issues/49#issuecomment-626251114 Alpine won't implement it, at least not in v2. Basic cases can be implemented using the event pattern. For complex cases, there's is a third party library called spruce.
Thanks @SimoTod I never knew about Spruce, super handy! I figured it'll be addressed in V3. Thanks.
Thanks @SimoTod I never knew about Spruce, super handy! I figured it'll be addressed in V3. Thanks.
The idea is that Alpine V3 might provide global stores (which you currently would have to use Spruce for) that's all subject to change though
What if I want to pass data in x-for to child component?
<template x-for="(pet, index) in pets" :key="index">
// I want to create a new component for pet card
<div x-data="{name:''}" x-init={name: pet.name}>
.....
</div>
</template>
Is there any solution for this?
I found the solution ))
https://twitter.com/hugo__df/status/1310611867954556929?utm_source=alpinejs&utm_medium=email
However, I want to know if this is the best one for now?
@PonyJackal Yes that's a fine solution. Or otherwise there are some helpers here you can use ($parent
/$component
):
https://github.com/alpine-collective/alpine-magic-helpers
And if you want something more to store and access all your data, try Spruce:
I tried to use $parent, but $parent is undefined
You have to include the helper's script on your page.
https://cdn.jsdelivr.net/gh/alpine-collective/alpine-magic-helpers@0.5.x/dist/component.min.js
Here's a demo: https://codepen.io/KevinBatdorf/pen/ZEpMeJJ
Note that I used $el.__x_for.c - 1
to get the x-for
index. I'm not sure how reliable that is. You may want to not use `x-for and instead implement the insertion manually.
I solved it like this:
<div x-data="{myVariableInParent: 'blah'}" x-bind:data-my-variable-in-parent="myVariableInParent">
<div x-data="{myLocalVariable: 'muah'}" x-init="myLocalVariable = $el.closest('[data-my-variable-in-parent]').dataset.myVariableInParent">
<span x-text="myLocalVariable"></span> <!-- will be 'blah' -->
</div>
</div>
Based on @KevinBatdorf 's solution
Hi @calebporzio, thanks for the amazing work so far. I was having a go with alpinejs and I noticed that, when there are nested components, the internal component cannot access the scope of the external one.
For example,
I would expect
span#s2
to display 'BAR' or, in alternative, i would expect to be able to reference foo2 in the internal data structure.I'm happy to work on a PR for this but I just wanted to check with you first in case this behaviour is expected and you do not want components to access external scopes.
Thanks, Simone