【问题标题】:Trouble on binding links with HTML5 'data-*' attributes使用 HTML5 'data-*' 属性绑定链接时遇到问题
【发布时间】:2014-06-04 04:14:04
【问题描述】:

我正在使用 Ruby on Rails 4,并且我有以下代码:

# view.html.erb

link_to("Title 1", url1, :remote => true, :method => :patch, :data => {:type => :html, :custom => true}
# <a rel="nofollow" href="/url1" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 1</a>

link_to("Title 2", url2, :remote => true, :method => :patch, :data => {:type => :html, :custom => true}
# <a rel="nofollow" href="/url2" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 2</a>

link_to("Title 3", url3, :remote => true, :method => :patch, :data => {:type => :html, :custom => true}
# <a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 3</a>


# application.js

$(document).ready(function() {
  $('a[data-remote][data-custom]').bind({
    click: function(event) {
      $(document).on('ajax:success', function(xhr, data, status) {
        $(this).replaceWith(data);
      });
    }
  });
});

例如,当点击链接Title 1 时,成功时,响应/返回的数据为以下链接(点击链接Title 2Title 3 时的行为相同):

link_to("Replaced 1", url1, :remote => true, :method => :patch, :data => {:type => :html, :custom => true}
# <a rel="nofollow" href="/url1" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 1</a>

如您所见,响应/返回的链接与原始链接几乎相同(即,它具有 data-* 属性,就像原始点击的链接一样),因此 JavaScript 绑定应该在该链接之后发生它取代了 DOM。

但是,如果我继续像 Title 2 一样单击其他链接,那么前端内容中的 Title 1Title 2 链接都会被替换,从而生成以下完整的 HTML 代码:

<a rel="nofollow" href="/url2" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 2</a>
<a rel="nofollow" href="/url2" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 2</a>
<a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 3</a>

为了完整起见,当我单击Title 3 时,会生成以下整个 HTML 代码:

<a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 3</a>
<a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 3</a>
<a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Replaced 3</a>

似乎 JavaScript 绑定没有按预期工作(注意重复的 Replaced &lt;N&gt; 链接)。我不明白为什么会发生这种情况,但预期的行为是每次单击该链接时只替换一个链接。

有什么问题?我该如何解决?

【问题讨论】:

  • 你能添加代码来展示你的 AJAX 功能是如何工作的吗?
  • @awexfwex - 是的,我可以添加代码,但我不知道什么代码。 ruby-on-rails 问题标签(您在编辑问题本身后删除)在那里,因为 link_to(..., :remote =&gt; true, :method =&gt; :patch, ...a Rails AJAX functionality
  • 某处,您必须有一些 Javascript 代码执行实际的 ajax 调用。发布那个。 ruby 代码只是生成要使用的 html,对于这个问题似乎没有必要。
  • 执行 AJAX 调用的代码在 rails.js 文件中的某处。
  • 好的,有道理。我完全错了。我会更新我的答案。

标签: javascript jquery ruby-on-rails ajax html


【解决方案1】:

绑定函数在调用时将事件处理程序附加到实际元素。因此,当您重新创建链接时,它没有为单击附加事件处理程序。相反,您应该使用 .on(..) 或 .delegate(..),并将事件处理程序本身附加到链接上方的包装元素。

相反,每次单击链接时,您都会创建一个新的 ajax 成功处理程序,因此它们会建立起来。我不确定您的 AJAX 功能是如何实现的,但是您应该将 ajax:success 事件仅附加到使用它的函数/对象,或者仅将其附加到文档一次,您需要在其中传递单击以启动请求的元素。

未经测试的示例代码:

<script type="text/javascript">
    $(document).ready(function () {
        $("#link-list").on('ajax:success', "a[data-remote][data-custom]", function(xhr, data, status) {
            $(this).replaceWith(data);
        });
    });
</script>
 <div id="link-list"> <!-- // wrapping element to attach event handlers to -->
    <a rel="nofollow" href="/url1" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 1</a>
    <a rel="nofollow" href="/url2" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 2</a>
    <a rel="nofollow" href="/url3" data-type="html" data-custom="true" data-remote="true" data-method="patch">Title 3</a>
</div>

【讨论】:

  • 我尝试了您的代码,它生成的行为与问题中描述的完全相同。我认为这个问题与绑定有关,因为它绑定用于替换所有链接,而不仅仅是一个。当您说“您应该只将事件附加到使用它的对象上”时,您可能是正确的。
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
相关资源
最近更新 更多