Alpine JS:x-show 对异步函数中的变量变化没有反应

Alpine JS: x-show not reacting to variable change in async function

我正在尝试使用 Alpine JS 构建登录模式。打开页面时,模态最初显示。我这样定义它:

<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>

相应的Javascript部分如下所示(省略了一些与表格数据有关的变量。):

<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>

我在这里试图实现的是此时关闭模态。然而,尽管变量被正确设置为 false,模态仍然可见。

我知道这与在异步函数中设置的变量有关。但是我不知道如何让它工作,到目前为止还没有找到做类似事情的教程。

感谢所有帮助。

问题是 login() 函数不是有效的 Alpine.js 组件。它没有 return 任何数据,因此 showLoginModal 不是反应性的,因此 Alpine.js 无法检测到您何时更改变量的值。使用 Alpine.data()loginComponent 应如下所示:

<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>

请注意,我们必须在组件定义中使用 this. 前缀来访问 Alpine.js 数据(反应式)。