我是阿尔卑斯山的新手,我一直在努力思考如何让这样的情景发生:
假设我有一个服务器端构建的页面,其中包含一些按钮,代表时事通讯,用户可以注册。用户可能已经注册了一些,我们还需要通过添加css-类.i.e is-signed-up来说明这一点。
最初的服务器端标记可以是这样的:
<button id='newsletter-1' class='newsletter-signup'>Newsletter 1</button>
<div>some content here...</div>
<button id='newsletter-2' class='newsletter-signup'>Newsletter 2</button>
<div>more content here...</div>
<button id='newsletter-3' class='newsletter-signup'>Newsletter 3</button>
<div>and here...</div>
<button id='newsletter-4' class='newsletter-signup'>Newsletter 4</button>(当全部加载完毕后,<button>应允许用户直接订阅或取消订阅时事通讯,方法是单击其中一个按钮,该按钮将相应地切换is-signed-up css类。)
无论如何,我从端点中获取一些json,它可能如下所示:
{"newsletters":[
{"newsletter":"newsletter-1"},
{"newsletter":"newsletter-2"},
{"newsletter":"newsletter-4"}
]}我想它看起来也可能是这样的:
{"newsletters":["newsletter-1", "newsletter-2", "newsletter-4"]}或者其他一些结构,但是情况是,用户已经注册了时事通讯1、2和4,而不是通讯3,我们不知道这一点,直到我们从端点获得JSON。
(但也许第一个变体更容易映射到模型,我猜.)
总之,我想做三件事:
使用特定的时事通讯id (即“时事通讯-2”)获取模型和dom元素之间的关系--即使模型中不存在确切的id。如果用户已经注册了时事通讯,则向相应的accordingly.添加is-signed-up css-类以向用户显示其状态。
我有一个想法,我可能需要“准备”每个通讯--预先准备一些阿尔卑斯-属性,比如'x-model='newsletter-2',但是我仍然不确定在阿尔卑斯初始化时如何将它们绑定在一起,而且我有来自端点的数据,
我该怎么做这样的事?
事先非常感谢!
发布于 2022-05-20 09:13:24
因此,我们这里的基本任务是在单击按钮时将特定项添加/移除到列表中。这里我定义了两个组件:newsletter组件使用Alpine.data()创建数据(subs数组),提供切换方法(toggle_subscription(which))和检查方法(is_subscribed(which)),我们可以使用它们将正确的CSS类设置为按钮。它还处理init()方法中的数据获取,该方法在组件初始化后自动执行。我还创建了一个save方法,我们可以使用它将订阅列表发送回后端。
第二个组件subButton和Alpine.bind()只是为了使HTML代码更加紧凑和可读性更好。(我们可以将每个属性直接放到按钮中。)因此,在单击事件时,它用当前时事通讯的键调用toggle_subscription作为添加/删除它的参数。此外,如果当前时事通讯在列表中,则将bg-red CSS类绑定到按钮。为此,我们使用在主组件中定义的is_subscribed方法。
.bg-red {
background-color: Tomato;
}<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<div x-data="newsletter">
<button x-bind="subButton('newsletter-1')">Newsletter 1</button>
<button x-bind="subButton('newsletter-2')">Newsletter 2</button>
<button x-bind="subButton('newsletter-3')">Newsletter 3</button>
<button x-bind="subButton('newsletter-4')">Newsletter 4</button>
<div>
<button @click="save">Save</button>
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('newsletter', () => ({
subs: [],
init() {
// Fetch list of subscribed newsletters from backend
this.subs = ['newsletter-1', 'newsletter-2', 'newsletter-4']
},
toggle_subscription(which) {
if (this.subs.includes(which)) {
this.subs = this.subs.filter(item => item !== which)
}
else {
this.subs.push(which)
}
},
is_subscribed(which) {
return this.subs.includes(which)
},
save() {
// Send this.sub to the backend to save active state.
}
}))
Alpine.bind('subButton', (key) => ({
'@click'() {
this.toggle_subscription(key)
},
':class'() {
return this.is_subscribed(key) && 'bg-red'
}
}))
})
</script>
https://stackoverflow.com/questions/72314721
复制相似问题