刺激:如何处理具有相同目标名称的重复项目

11

我有一个项目列表,每个项目都有一个链接可以点击以编辑它。我正在使用 Stimulus 使编辑“模态”表单在单击编辑链接时可见。要编辑的内容的 ID 存在于列表中相应的链接标记上的 id= 中。

因此,编辑链接看起来像这样:

<td>
  <a data-action="click->content#edit"
     data-target="content.editBtn"
     id="<%= url_for(content) %>")>
    Edit
  </a>
</td>

这个想法是,Stimulus控制器中的content#edit操作会检查并定位它的id,并使用它来编辑正确的行。

然而,我遇到的问题是,所有行都具有相同名称的data-target,结果绑定了错误的目标(第一个?)。

但是,如果我想通过将id附加到它上面使每个data-target不同,那么现在在controller.js中有一个很长的目标列表,这样做就没有意义了。

应该如何处理才是正确的呢?


为了确保我们在同一个页面上,你是为每个显示的项加载一个模态框吗? - s_dolan
我正在尝试避免这种情况。我有一个模态表单标记的实例,它将被显示以编辑正在编辑的特定行。 - pitosalas
如果您像其他问题一样使用Rails作为后端,可能会有更简单的非Stimulus解决方案。要使用Stimulus,您需要从服务器或DOM获取项目的数据,将其显示在表单中,然后通过JavaScript将正确的表单与正确的ID提交到服务器。为什么不为每个项目都有一个远程link_to按钮来编辑操作呢?Rails会收到一个JS请求到edit控制器动作,并且您可以使用Ruby对象中的数据加载模态表单。如果您喜欢这种方法,我可以写出完整的答案。 - s_dolan
是的,听起来你对Stimulus的使用情况做出了准确的诊断,并且使用远程表单会更好、更容易。我的具体目标确实是学习Stimulus,这一点我已经做到了 :) 但是这个用例有点复杂! - pitosalas
我认为Stimulus仍然是这种情况下一个很棒的工具,只是你所使用的部分不适用。我会利用这个机会来创建一个Stimulus控制器,监听ajax->send/error/complete事件并自动禁用/启用按钮,在按钮上设置加载旋转器,并关闭模态框。这些至少是可以添加一些Stimulus非常容易实现的功能的好地方。 - s_dolan
@S_dolan,您能否发布一个答案(复制您的评论),我会点赞并接受!谢谢! - pitosalas
3个回答

6

这实际上是 Stimulus 的一个很好的应用,因为它是模块化的。您为每一行添加一个控制器,而不是将控制器放在页面或表格周围。

<tr data-controller="content">
  <td>
    <a data-action="click->content#edit" data-target="content.editBtn" id="<%= url_for(content) %>")>
      Edit
    </a>
  </td>
</tr>

4
如果你像你的其他问题所暗示的那样使用Rails作为后端,可能会有更简单、非Stimulus的解决方案。要使用Stimulus,你需要从服务器或DOM获取项目的数据,将其显示在表单中,然后通过JavaScript向服务器提交正确的ID和表单。为什么不为每个项目添加一个远程的link_to按钮来调用edit操作呢?Rails会收到一个JS请求,调用edit控制器动作,并从Ruby对象中加载具有数据的模态表单。
如果您在表单上使用了Stimulus,则可以利用此机会创建一个Stimulus控制器,监听ajax->send/error/complete事件并自动禁用/启用按钮,在按钮上设置加载旋转器,并关闭模态框。这些都是适合使用Stimulus添加功能的良好区域。

3

我之前遇到过类似的问题。
这个链接可能会有所帮助: https://codepen.io/smashingmag/pen/ExPprPG

基本上,你可以像这样循环处理目标:

for(let tgt of this.mySameNameTargets) {
  tgt.innerHTML = "Some Value"
}

假设您在控制器中有以下内容:
state targets = ["mySameName"]

您可以将id放在每一行中,使用“操作参数”也可以实现这一点: https://stimulus.hotwired.dev/reference/actions#action-parameters 从这些文档中看来,它是这样的:
<div data-controller="item spinner">
  <button data-action="item#upvote spinner#start" 
    data-item-id-param="12345" 
    data-item-url-param="/votes"
    data-item-payload-param='{"value":"1234567"}' 
    data-item-active-param="true"></button>
</div>

// ItemController
upvote(event) {
  // { id: 12345, url: "/votes", active: true, payload: { value: 1234567 } }
  console.log(event.params) 
}

你可以在参数中设置该行中项目的id,然后当他们点击该行时,你可以从参数中找到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接