Estoy tratando de construir un Login-Modal con Alpine JS. El modal se muestra inicialmente al abrir la página. Yo lo defino como:
<div x-data="login()" x-show="showLoginModal" x-cloak x-transition> <form action="/token" method="POST" class="mt-8" @submit.prevent="submitData"> <!-- defining the login form --> </form> </div>La parte de Javascript correspondiente se ve así (omitiendo algunas variables relacionadas con los datos del formulario):
<script> let token = undefined let showLoginModal = false function login() { async submitData() { await fetch(await fetch('/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formBody }) .then((response) => { if (response.status === 200) { return response.json(); } else { throw new Error("Login failed."); } }).then((data) => { token = data.access_token showLoginModal = false }) } } </script>Lo que estoy tratando de lograr aquí es que el modal esté cerrado en este punto. Sin embargo, aunque la variable se establece correctamente en falso, el modal permanece visible.
Soy consciente de que esto tiene algo que ver con la configuración de la variable en una función asíncrona. Sin embargo, no sé cómo hacer que funcione y hasta ahora no he encontrado un tutorial que haga algo similar.
Toda ayuda apreciada.
El problema es que la función login() no es un componente Alpine.js válido. No devuelve ningún dato, por lo que showLoginModal no es reactivo, por lo que Alpine.js no puede detectar cuándo muta el valor de la variable. Un componente de inicio de sesión que use loginComponent () debería verse así:
<div x-data="loginComponent()" x-show="showLoginModal" x-cloak x-transition> <form action="/token" method="POST" class="mt-8" @submit.prevent="submitData"> <!-- defining the login form --> </form> </div> <script> document.addEventListener('alpine:init', () => { Alpine.data('loginComponent', () => ({ showLoginModal: true, token: undefined, async submitData() { await fetch(...).then((data) => { this.token = data.access_token this.showLoginModal = false }) } })) }) </script> Tenga en cuenta que tenemos que usar el this. prefijo en la definición del componente para acceder a los datos de Alpine.js (que son reactivos).