Rails 4 Turbolinks使表单提交多次

5
我使用一些在Rails 3上运行良好但在Rails 4上却不行的代码,我猜测是由Turbolinks引起的,但我对它了解不多,无法深入挖掘解决我的问题,以下是代码:
视图:
a/v/m/_new_comment.slim                                                                                                                             
.new-comment                                                                                                                                         
- if current_user
  = render "editor_toolbar"
  = form_for(Comment.new, :remote => true, :url => mission_comments_path(@mission)) do |f|
  = f.text_area :content, :class => "span10",
    :rows => "4", :tabindex => "1"
  #preview.hidden
    = "Loading..." 
  = f.submit t("missions.submit_comment"),
    "data-disable-with" => t("missions.submitting"),
    :class => "btn btn-primary", :tabindex => "2"
- else
  = render "need_login_to_comment"

控制器:
def create
  @mission = Mission.find(params[:mission_id])
  @comment = @mission.comments.build(comment_params)
  @comment.user = current_user

  if @comment.save
  @mission.events.create(user: current_user, action: "comment")
  render layout: false
end

and js:

<% if @comment.errors.any? %>                                                                                                                        
  $(".new-comment textarea").focus();
<% else %>
  $(".comments").append("<%= j (render @comment, :index => @mission.comments.count-1) %>");
  $(".new-comment #preview").addClass("hidden").html('');
  $(".new-comment textarea").css("display", "block").val('');
  $(".editor-toolbar .preview").removeClass("active");
  $(".editor-toolbar .edit").addClass("active");
<% end %>

我有两个问题关于这段代码,第一个问题是:像这样的控制器代码不起作用,js代码被传输到客户端但没有运行,我必须在该操作底部添加render layout: false,在Rails 3中不需要这样做。
第二个问题是:当我第一次访问此页面并重新加载页面时,评论功能可以正常工作,但是如果我从其他页面点击链接跳转到此页面,提交此表单将导致ajax请求调用多次,将创建多个评论。
谢谢。

我无法评论您的具体代码,但您可以尝试删除Turbo-links并查看是否可以正常工作。删除Turbolinks的说明 - Althaf Hameez
从应用程序.js文件中删除turbolinks,使其正常工作。 - William Herry
3个回答

16

通过将= javascript_include_tag "application", "data-turbolinks-track" => true从body移动到head,解决了这个问题,感谢你们的帮助。


4
谢谢建议!对我帮助很大,我一个小时想不出问题所在! 应该在文档中找到相关信息,通常建议将脚本移动到 </body> 前面。 - user1932315

10
你可以将它放在文档正文中,只需在script标签中添加如下内容:
"data-turbolinks-eval" => false

一般来说,使用turbolinks时,最好确保你的代码是“幂等”的,这样如果它运行多次,绑定也不会设置多次。

最好的方法是,不要使用$('blah').bind(),而是先调用unbind:

 $('blah').unbind('click').bind('click', function() {

是的。有一些复杂的插件可以尝试解决它,但我发现unbind()更简单和更有效,尽管它会添加一些丑陋! - Kevin
1
与其解绑和重新绑定,最好使用 $(document).on('click', '.blah', function(e) {}); - Jezen Thomas

1

你遇到问题的一个可能原因是如果你在每个页面都包含了这个js。我的理解是它会将js添加到头部,如果你在多个页面上都包含了它,你可能会发现自己绑定ajax多次。话虽如此,从我看到的内容来看,你包含js的方式并不明显。你可以通过仅在你的application.js文件中包含js文件来解决这个问题。


我在应用程序中只包含了JS文件,所以我认为这可能不是原因。顺便说一下,上面的视图代码被包含为部分,这可能是原因吗? - William Herry

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