【问题标题】:Rails - turbolinks issueRails - turbolinks问题
【发布时间】:2017-06-02 19:14:12
【问题描述】:

我试图在redirect_to update_path 之后启用jquery,我尝试将turbolinks 全部禁用,但这无济于事。我目前正在成功更新时执行 window.location.reload() 函数,但这是一个非常丑陋的解决方法。有没有更好的方法来做到这一点?

这是在 .js 中

    $.ajax ({
         type: 'POST',
         url: "http://localhost:3000/chess/" + sv + "/" + val,
         success: function(d){
            count = 0;
            window.location.reload();
         }

       });

这在 controller.rb 中:

def move
  piece = params[:piece].chomp(",").each_char.map(&:to_i)
  a = piece[0]
  b = piece[2]

  square = params[:square].chomp(",").each_char.map(&:to_i)
  c= square[0]
  d= square[2]

  pieceVal = @@arr[a][b]
  squareVal = @@arr[c][d]

  @@arr = @@arr.each_with_index.map do | e1, i1|
    @@arr[i1].each_with_index.map do |e2, i2|
       if (i1 === a && i2 ===b)
         @@arr[a][b]  = [0]
       elsif (i1 === c && i2 === d)
        @@arr[c][d] = pieceVal
       else
        e2 = @@arr[i1][i2] 
       end
    end
  end

  redirect_to update_path



end

我尝试在重定向后设置 turbolinks: false,但这只是完全禁用了 jquery。

【问题讨论】:

  • 你想做什么? move方法完成后更新棋盘吧?
  • 没错
  • 我周围的工作有效,只是不是很好,我很好奇这里是否缺少一些可以提供更好解决方案的东西。

标签: jquery ruby-on-rails turbolinks


【解决方案1】:

对不起这本书:我想我会解释发生了什么,而不是仅仅给你一个答案。

问题

所以 turbolinks 在这里不是问题。问题在于您的实施(问题不大)

当您编写redirect_to ... 时,它会告诉您的浏览器转到响应标头中指定的Location。它不返回正文(就像 GET 请求返回 HTML 正文)

实现

这里的诀窍是实现某种方式,用新的棋盘替换棋盘的内容,而无需重新加载整个页面。因为我们已经知道新棋盘的输出,所以我们可以使用 javascript 来完成。

HTTP 请求示例

HTTP 请求(将它们视为控制器方法的结果)可以响应许多不同的格式。您已经熟悉 HTML 响应,这些都是标准的。还有其他格式,包括(但不限于)XHR 请求(代表 XML HTTP 请求)和 JSON 请求。

Similarly to my response to a question you asked yesterday,您可以通过在application_controller.rb 中添加以下内容来查看差异(假设您也添加了其他代码):

def test
  respond_to do |format|
    format.html { render :text => "I love me some #{params[:cookies]} with my #{params[:cream]}" } 
    format.json { render :json => { :result => "I love me some #{params[:cookies]} with my #{params[:cream]}", :cookie_result => params[:cookies], :what_kind_of_cream_did_he_want => params[:cream] } 
    format.js { render :text => "alert('I love me some #{params[:cookies]} with my #{params[:cream]}');" } 
  end
end

然后在浏览器中点击localhost:3000/chocolate-chip/and/milk.json 以查看生成的 JSON,例如。

注意:Rails 期望 XHR 请求(大多数时候是对 ajax 请求的响应)具有 formatjs,不要让它绊倒你。

我们不能调用localhost:3000/chocolate-chip/and/milk.xhr,因为我们没有它的MIME 类型;浏览器不知道如何处理它,我们的 Rails 服务器(如 puma 或 webrick)不知道如何处理它。这很好,也很正常。

XHR 请求是客户端的事情(就您的 HTML/JS 而言)。它们可以比作您发送 POST 请求的方式:您指示浏览器做某事。

我们要做的是告诉浏览器发送一个 ajax 请求。值得庆幸的是,如果您使用的是 jquery_ujs,Rails 让这一切变得容易(您可能是,只需检查您的 application.js 文件即可)

要查看上面示例中生成的 XHR 响应,请将 <%= link_to "What kind of cookies", "/chocolate-chip/and/milk", :remote => true %> 放在您可以查看的现有 *.html.erb 文件中的某个位置。继续并单击它。它应该返回一个警告框,表明我们对巧克力片和牛奶的热爱。

如您所见,我们的内联 javascript 已执行。

解决方案

所以现在的问题是“我怎样才能让我的棋盘被这个替换?”

对此的最佳做法是使用 partial_board.html.erb 来呈现板。 <div id="chess_board_wrapper"><%= render 'board' %></div> 如果它与控制器期望的视图路径相同(根据 Rails 约定,您应该遵循它们)。注意:在渲染棋盘的父元素中有一个 ID 属性在这里很重要;我们稍后会用到它。

_board.html.erb 中,只需复制粘贴您现有的棋盘标记即可。

现在,创建一个 move.js.erb(是的,.js.erb),就像创建 new.html.erb 一样。在 move.js.erb 文件中,您可以简单地编写 $('#chess_board_wrapper').html('<%=j render "board" %>');

然后,告诉您的 move 方法响应 XHR 请求,

def move
  # ...
  respond_to do |format|
    format.js # should automatically read move.js.erb 
    format.html { redirect_to update_path } 
  end
end

剩下的就是历史了。我很确定您也可以从 ajax 调用中删除 success 函数。

【讨论】:

  • 非常感谢您的详细回复,稍后将尝试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-15
相关资源
最近更新 更多