Reputation: 1677
I'm just starting out with Alpine.js, I understand the basics but I'm having trouble applying them when moving functions outside of inline script tags.
For example, in index.html
:
<div x-data="{ loading: false }"/>
<button
onClick="post()"
:class="{ 'active': loading === true }"
>
Post Comment
</button>
</div>
if post()
was in main.ts
:
const postComment = () => {
this.loading = true;
};
window.postComment = postComment;
How do I make it so that this
isn't undefined?
I've found plenty of examples where functions are kept within index.html
, but none where they're in a separate file.
Upvotes: 3
Views: 27143
Reputation: 5774
You'll need to add the method to the AlpineJs instance to access the same scope. But you can do this with some object destructuring using the spread ...
operator:
In the page:
<div x-data="{
isLoading: false,
...utils
}">
// Your content
</div>
Then in your external script file:
const utils = {
post(){
this.isLoading = true
}
}
window.utils = utils
The nice thing about this is you could put everything you need for a loading indicator in this external object to use as a mixin wherever you need it.
Here's a working example: https://codepen.io/stephenoldham/pen/BapvyYr
Update for AlpineJs v3:
If you're trying to achieve the same goal in the latest version of AlpineJs you'll need to use the Data Directive:
In the page:
<div x-data="utils">
// Your content
</div>
Then in your external script file:
document.addEventListener('alpine:init', () => {
Alpine.data('utils', () => ({
isLoading: false,
post(){
this.isLoading = true
setTimeout(() => {
this.isLoading = false
}, 3000)
}
}))
})
Here's a working example: https://codepen.io/stephenoldham-the-vuer/pen/dyJEjRx?editors=1100
Further reading in the docs covers how to set initial values and more: https://alpinejs.dev/globals/alpine-data
Upvotes: 11