数据类型 JS 的 Rails 4 远程请求回调问题

Posted

技术标签:

【中文标题】数据类型 JS 的 Rails 4 远程请求回调问题【英文标题】:Rails 4 remote request callback issue with data-type JS 【发布时间】:2019-03-08 18:10:21 【问题描述】:

我在 Rails 4.1.6、Ruby 2.3.0、JQuery 1.11.1(jquery-rails 3.1.1、coffee-rails 4.0.1)上遇到问题,我将举一个简单的例子来解释我的问题:

我有一个视图,其中包含使用 Ajax 创建的项目列表。在它上面,有一个按钮可以远程创建一个新的空项目:

button_to "Add Item",
           action: :create ,
          form:  id: "add_item_form" ,
          remote: true

在我的 javascript 中,我已经连接了该事件:

$('#add_item_form').on('ajax:success', function (e, data)
  alert('Success!');

控制器:

def create
  @item = Item.new()
  @item.save!
  respond_to do |format|
    format.js
  end
end

因为create方法只响应JS,它会尝试渲染一个同名的JS视图,这很好:

create.js.erb

$('#item_list').append("<%= escape_javascript(render partial: 'item_li', locals:  item: @item ) %>")

在局部:

_item_li.html.erb

<li>
  <%= form_for(item, remote: true) do |f| %>
    // List of item fields from model
  <% end %>
</li>

如果我运行该代码,它可以正常工作,并且警报显示“成功!”,回调会在部分视图呈现后立即执行。问题是,该警报在哪里,我想用新创建的项目的信息(如 id)做一些事情,但我找不到让我在控制器中创建的项目回到回调函数。

由于我使用的是 CoffeeScript,因此我的主 javascript 文件和 create.js.erb 无法相互通信(无法从其他文件访问主文件上声明的函数)。

如果我将控制器更改为:

respond_to do |format|
  format.js
  format.json  render json: @item 
end

并将按钮上的数据类型更改为“json”,我将在回调中获取项目,但永远无法到达部分视图。如果我添加这两种数据类型,那么我会在回调的“数据”变量中获得 create.js.erb 上的任何内容。

这个问题的最佳解决方案是什么?

【问题讨论】:

【参考方案1】:

如果我正确理解您的问题,您希望能够在回调中使用 @item 做一些事情。

您应该能够在create.js.erb 中操作@item,而不是使用success 回调。

为了测试这个,我会删除这个:

$('#add_item_form').on('ajax:success', function (e, data) alert('Success!');

然后将一些 Javascript 代码添加到您的 create.js.erb 文件中:

$('#item_list').append("<%= escape_javascript(render partial: 'item_li', locals:  item: @item ) %>")
alert('Success!');
// Do whatever you want here, @item should be accessible 

【讨论】:

是的,根据我对问题的理解,这似乎应该有效。此外,OP 可能会尝试将“主 javascript 文件”或 Coffeescript 文件中的函数绑定到 window 对象,以便在任何地方都可以访问它们。 这是我目前的解决方法,但我希望我可以在回调中获得@item,因为我在该文件上有几个市长函数,我不想重复代码 @NMPennypacker 我想避免使函数成为全局函数,它们只针对一个视图。我想到的另一个解决方法是在“create.js.erb”上为新创建的项目添加一个“new”类,然后在回调中使用 $('li.new') 找到它,做我必须做的事情,然后最后删除“新”类。但我的意思是,必须有更好的方法,对吧? @GujMil 为什么不直接把相关的 Javascript 放在你的视图文件中呢?我一直这样做。

以上是关于数据类型 JS 的 Rails 4 远程请求回调问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 4 中正确实现 Parsley.js 自定义远程验证器

试图找出 Ruby on Rails 远程:真正的回调

rails :: 如何评估 js 响应

Rails 6.0.4 远程:true 不在浏览器中 js/ajax 渲染 _partial.html.erb

js异步回调

具有虚拟属性的 after_save 回调 Rails 3