这里最好的其他答案是正确的,这不能通过将 javascript 变量传递到 erb 部分来完成,因为它是在服务器上呈现的,而不是在客户端上呈现的。
但是,由于任何寻找这个的人都可能对我在这里看不到的变通解决方案感兴趣,所以我将发布这个适用于 Rails UJS 和 Turbolinks 的示例。
首先,您将控制器设置为以 HTML 形式返回部分内容:
format.html { render partial: "new_expense" }
接下来,在app/views/expenses/new_daily.js.erb中写一个javascript AJAX函数:
var i = parseInt($('#daily').attr('data-num')) + 1;
$.ajax({
url: '/daily',
type: 'GET',
dataType: 'html',
contentType: "application/html",
success: function(response) {
$('#daily').replaceWith(response)
$('#daily').attr('data-num', i);
}
});
这将使您的 Rails 部分成为一个 html 片段,您可以使用它来替换渲染页面的该部分。您可以使用 jQuery 获取您的 data-num 属性值,对其进行一些数学运算,替换视图中的部分,然后再次设置属性值。
您可能会问,为什么不费吹灰之力在页面上获取 Rails 部分并替换它,而不是仅获取数据属性,对其进行数学运算并进行设置?答案是,这是最好的,也许是唯一的方法,当使用 UJS 渲染 Rails 部分,同时处理对操作的异步响应时,这是非常重要的。
如果您在create.js.erb 模板中处理来自服务器的异步响应,那么您的变量(例如@daily)将不会反映请求完成后完成的工作(例如,如果有一直在像 Sidekiq 这样的后台服务器上处理)。在这种情况下,您没有最新的操作响应变量可以传递到 js.erb 文件中的 Rails 部分,但您也不能将 javascript data 响应传递到您的部分中,正如在这个问题。
据我所知,这种方法是在收到对异步响应的响应(未显示)后获得完全最新的部分的唯一方法。这可以让您获得最新的部分,允许您将 javascript 放入其中,并且足够灵活,可以在几乎任何用例中工作。