Alpinejs async computed property with spinner



我有一个范围滑块输入,它应该触发一个异步计算属性来显示。当它等待响应时,我想显示一个旋转器。看看下面我想到了什么。我觉得我把事情弄得太复杂了,有时旋转器和结果标题同时显示(!)。是否有一个更好的方法做异步计算道具与Alpinejs?

<script src="//unpkg.com/alpinejs" defer></script>
<script>
async function getTitle(id) {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
const data = await response.json();
await new Promise(resolve => setTimeout(resolve, 2500)) // adds some extra slowness
return data.title.toUpperCase()
}
</script>
<div x-data="{ todoId: 10, title: 'A PRELODED TODO TITLE' }">
<h3>Title formatter</h3>
<p>Grab a todo via API and uppercases title </p>
<input x-model="todoId" x-on:change="console.log('change!'); title = null" id="steps-range" type="range" min="0" max="50" step="1">
<div x-show="title !== null" x-html="title ?? (title = (await getTitle(todoId)))"></div>
<div x-show="title === null">Loading ...</div>
</div>

JSFIDDLE

我已经调整了你的例子,以显示处理相同问题的不同方式,它在Alpine.js方面简化了,我已经调整了你的函数,以协助标签问题。

<script src="//unpkg.com/alpinejs" defer></script>
<style>
.error {
color: red;
}

.success {
color: blue;
}

.loading {
color: orange;
}
</style>
<div x-data="{
todoId: 10,
title: 'A PRELODED TODO TITLE',
error: false,
loading: false,
async getTitle(id) {
this.success = true
this.error = false
this.loading = true
this.title = 'Loading ...'
await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
.then(res => res.json())
.then(async(res) => {
await new Promise(resolve => setTimeout(resolve, 100)) // adds some extra slowness
if(res.id === parseInt(this.todoId)) {
this.loading = false
this.success = true
this.title = res.title.toUpperCase()
}
return
}).catch((e) => {
this.loading = false
this.title = e.message
this.error = true
})
}
}" x-init="$watch('todoId', (newValue, oldValue) => {
newValue != oldValue ? $nextTick(async() => { getTitle(todoId) }) : null
})">
<h3>Title formatter</h3>
<p>Grab a todo via API and uppercases title</p>
<input x-model="todoId" id="steps-range" type="range" min="0" max="50" step="1" />
<div x-show="title" :class="{'error': error, 'success': !error, 'loading': loading}" x-text="title"></div>
</div>

最新更新