首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Alpine.js与“静态”服务器端标记混合,同时获得绑定的好处,等等

将Alpine.js与“静态”服务器端标记混合,同时获得绑定的好处,等等
EN

Stack Overflow用户
提问于 2022-05-20 06:51:57
回答 1查看 105关注 0票数 0

我是阿尔卑斯山的新手,我一直在努力思考如何让这样的情景发生:

假设我有一个服务器端构建的页面,其中包含一些按钮,代表时事通讯,用户可以注册。用户可能已经注册了一些,我们还需要通过添加css-类.i.e is-signed-up来说明这一点。

最初的服务器端标记可以是这样的:

代码语言:javascript
复制
<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,它可能如下所示:

代码语言:javascript
复制
{"newsletters":[    
    {"newsletter":"newsletter-1"},  
    {"newsletter":"newsletter-2"},
    {"newsletter":"newsletter-4"} 
]}

我想它看起来也可能是这样的:

代码语言:javascript
复制
{"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',但是我仍然不确定在阿尔卑斯初始化时如何将它们绑定在一起,而且我有来自端点的数据,

我该怎么做这样的事?

事先非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2022-05-20 09:13:24

因此,我们这里的基本任务是在单击按钮时将特定项添加/移除到列表中。这里我定义了两个组件:newsletter组件使用Alpine.data()创建数据(subs数组),提供切换方法(toggle_subscription(which))和检查方法(is_subscribed(which)),我们可以使用它们将正确的CSS类设置为按钮。它还处理init()方法中的数据获取,该方法在组件初始化后自动执行。我还创建了一个save方法,我们可以使用它将订阅列表发送回后端。

第二个组件subButtonAlpine.bind()只是为了使HTML代码更加紧凑和可读性更好。(我们可以将每个属性直接放到按钮中。)因此,在单击事件时,它用当前时事通讯的键调用toggle_subscription作为添加/删除它的参数。此外,如果当前时事通讯在列表中,则将bg-red CSS类绑定到按钮。为此,我们使用在主组件中定义的is_subscribed方法。

代码语言:javascript
复制
.bg-red {
    background-color: Tomato;
}
代码语言:javascript
复制
<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>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72314721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档