Ruby on Rails防止Turbolink劫持AJAX操作 [英] Ruby on Rails prevent Turbolinks from hijacking AJAX action

查看:100
本文介绍了Ruby on Rails防止Turbolink劫持AJAX操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将遵循RoR入门指南,并在进行过程中添加一些内容.具体来说,我要实现的是在步骤 5.13删除文章中,我使用AJAX而不是标准模式删除文章.

I am following along the RoR getting started guide and adding a few things as I go along. Specifically, what I would like to achieve is that in step 5.13 Deleting Articles, I delete an article using AJAX instead of using the standard pattern.

我想以与RoR的做事方式最相符的方式来做.阅读了在Rails中使用JavaScript 一章之后,以下步骤看起来像方式:

I want to do so in a way that fits in best with the RoR way of doing things. After reading the Working with JavaScript in Rails chapter, the following steps seemed like the way to go:

  1. 将属性 remote:true 添加到 link_to 帮助器(请参见代码段A)
  2. 通过添加 data:{turbolinks:false} (请参见代码段A)来禁用Turbolink链接此 link_to 帮助器(请参见代码段A)
  3. 向控制器添加一些逻辑,以确保返回JSON(请参见代码段B).
  4. 添加JavaScript,该JavaScript侦听 ajax:success 事件,然后对该项目进行动画处理(请参见代码段C).
  1. Add property remote: true to the link_to helper (See code snippet A)
  2. Disable turbolinks this link_to helper by adding data: {turbolinks: false} (See code snippet A)
  3. Add a some logic to the controller that will make sure JSON is returned (see code snippet B).
  4. Add JavaScript that listens for the ajax:success events and then animates the item away (see code snippet C).

代码段A

<td><%= link_to 'Destroy', 
        article_path(article),
        method: :delete,
        data: {turbolinks: false, remote: true},
        :class=> 'remove-article' %></td>

摘要B

def destroy  
    @article = Article.find(params[:id])

    respond_to do |format|
      if @article.destroy
        format.html { redirect_to articles_path }
        format.json { render json: @article }
      else
        format.html { render action: "index" }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end

end

代码段C

(function(){
  $(document).on('turbolinks:load', listenForArticleDelete);

  function listenForArticleDelete() {
    $('a.remove-article').on('ajax:success', function(e, data, status, xhr) {
      // e.preventDefault();
      console.log('DELETE: AJAX SUCCESS', e, '\n', data, '\n', status, '\n', xhr);
    });
  }
})();

这与我预期的不太一样:

This isn't quite working as I expected:

  • 禁用turbolinks无效:它仍在替换整个页面内容.
  • 事件 ajax:success 事件被触发,但是当我检查该事件的data属性时,我看到了一些奇怪的东西.似乎是Turbolinks将要做什么/刚刚完成(?!)的文字表示. Turbolinks.clearCache()Turbolinks.visit("http://localhost:3000/articles,{" action:" replace})
  • The turbolinks disabling hasn't worked: it is still replacing the full page content.
  • The event ajax:success event is triggered but when I inspect the data property of that event, I see some weird stuff. It seems a textual representation of what Turbolinks is about to do / has just done (?!). Turbolinks.clearCache() Turbolinks.visit("http://localhost:3000/articles", {"action":"replace"})

我显然对这个错误感到支配.有人可以向我解释我应该怎么做吗?IE.不仅是如何使其正常工作,而且还是以惯用的RoR方式进行的?

I am obviously doign this wrong. Can someone please explain to me how I should be doing this? I.e. not just how to get it to work, but also in an idiomatic RoR way?

我找出了罪魁祸首:它是片段B ,因为format.html在format.json之前运行.只需切换这两个即可解决问题:

I found out which part was the culprit: it was Snippet B because the format.html was being run before the format.json. Simply switching these two fixed the issue:

修订后的代码段A:

<!-- Default delete -> format.html -->
<td><%= link_to 'Destroy default', 
        article_path(article),
        method: :delete,
        :class=> 'remove-article' %></td>
<!-- aSync delete -> format.json -->
<td><%= link_to 'Destroy aSync', 
        article_path(article),
        method: :delete,
        remote: true,
        data: {turbolinks: false},
        :class=> 'remove-article' %></td>

修订后的代码段B:

def destroy  
    @article = Article.find(params[:id])

    respond_to do |format|
      if @article.destroy
        # Must place json before html, otherwise html will be executed
        format.json { render json: @article }
        format.html { redirect_to articles_path }
      else
        format.json { render json: @article.errors, status: :unprocessable_entity }
        format.html { render action: "index" }
      end
    end

end

推荐答案

我个人会以不同的方式来讨论.

I would come at this a different way personally.

查看:触发ajax调用以删除文章

View: trigger ajax call to delete article

<td><%= link_to 'Destroy default', article, method: :delete, :remote => true, :class=> 'remove-article' %></td>

控制器:

def destroy
    @article.destroy
    respond_to do |format|
        format.js
    end
end

这将处理destroy方法并返回javascript,默认情况下,它将与相关目录中的destroy.js.erb文件一起返回

this will process the destroy method and return javascript, by default this will return with the destroy.js.erb file in the relevant directory

destroy.js.erb:

destroy.js.erb:

$("#article").slideToggle(300, function(){

    $("#article").remove();

});

仅供参考: http://api.jquery.com/slidetoggle/

希望这会有所帮助

这篇关于Ruby on Rails防止Turbolink劫持AJAX操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆