在JavaScript函数内部进行的Rails调用中使用JavaScript变量:Ajax在这里有什么帮助?
我依靠JavaScript对象定义的变量来更新(重新呈现)视图中的RubyonRails部分,但它不起作用。据我所知,它告诉我实现这一点的唯一可能方法是使用Ajax调用,但是我对这一点还不熟悉,不能完全理解为什么(考虑到在定义Rails命令之前JavaScript变量是可用的),也不知道我应该如何做 我的Rails视图有一个我想要的HTML位在JavaScript函数内部进行的Rails调用中使用JavaScript变量:Ajax在这里有什么帮助?,javascript,ruby-on-rails,ajax,Javascript,Ruby On Rails,Ajax,我依靠JavaScript对象定义的变量来更新(重新呈现)视图中的RubyonRails部分,但它不起作用。据我所知,它告诉我实现这一点的唯一可能方法是使用Ajax调用,但是我对这一点还不熟悉,不能完全理解为什么(考虑到在定义Rails命令之前JavaScript变量是可用的),也不知道我应该如何做 我的Rails视图有一个我想要的HTML位 <div id="myevent"> <% if @pocket.events.any? %> <%
<div id="myevent">
<% if @pocket.events.any? %>
<%= @event = @pocket.events.first %>
<%= render @event %>
<% end %>
</div>
JavaScript变量“item”包含来自已单击节点的事件id。如您所知,上面的最后一行不起作用,Rails将引发ArgumentError,其中包含以下消息:
“nil”不是与ActiveModel兼容的对象。它必须实现:to_partial_path
如果我设置了一个硬编码的id,它确实可以工作,因此基本原理似乎是正确的:
$('#myevent').html("<%= escape_javascript render (@pocket.events.find_by id: 5) %>");
但是,它失败了,出现了一个ActiveRecord::RecordNotFound
错误,因为它实际上没有用JavaScript变量的值替换字符串“+item+”
:
Couldn't find Event with 'id'=+item+
“痛苦”在于,无论我如何尝试,我都找不到在Rails调用上使用JavaScript定义的变量的方法。看起来解决方案应该是使用Ajax调用,但我认为经过多次尝试后,我自己无法解决这个问题。我真的很想在这里帮忙。我认为代码的.erb部分只在呈现时被解析,因此当页面第一次呈现时,实际上没有任何
项可附加到该项上。反过来,当您硬编码它时,它能够解析ruby代码并正确呈现
因此,您确实需要联系服务器
我要做的是:
timeline.on('click', function (properties) {
var item = properties["item"];
$.ajax({
type: "POST",
url: '/route_to_your_controller',
data: { event_id: item },
dataType: 'json',
success: function(data) {
if (data['success']) {
$('#myevent').html(data['html']);
}
else {
alert('oopsss take care of this');
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
routes.rb
post '/route_to_your_controller', to: 'controller#spew_html'
然后,假设您在控制器上有此操作的路径:
def spew_html
# you should take care of failed finds, errors that might occur, have a before_action to check legality of ajax call, and even possibly accept only xhr, return false unless request.xhr? etc
event_id = params[:event_id]
html_partial = render_to_string 'shared/event', locals: { event_id: event_id }
respond_to do |format|
format.json { render json: { html: html_partial, success: true } }
end
end
作为奖励,我喜欢在可能的情况下实现的一种模式是,对任何ajax都使用相同的GET be POST路径,这样我就可以简单地执行以下操作:
$.ajax({
type: "POST",
url: window.location.pathname,
//...
});
并让控制器知道如何处理它。它不起作用,因为
中包含的所有内容都是在页面呈现之前处理的,所以您需要在服务器上设置项,而不是在客户端上。这就是为什么手动设置有效,而动态设置无效。正如您所提到的,这需要ajax;您可以阅读有关rails和ajax的内容。感谢您确认ajax确实是我们的发展方向。非常感谢您深思熟虑的回复,Micael!您的解决方案切中要害,为我解决了问题,非常感谢!我会把它标记为“已解决”,但这里似乎没有这个选项。@laudares在左边,很高兴它能帮上忙。我四处寻找已解决的按钮,但它没有显示给我-相反,当我尝试向上投票你的答案时,我得到了一个答案“声誉低于15的人所投的票会被记录下来,但不要改变公布的帖子分数”@paul roub-我还能做些什么来“关闭”我的求助请求吗?
post '/route_to_your_controller', to: 'controller#spew_html'
def spew_html
# you should take care of failed finds, errors that might occur, have a before_action to check legality of ajax call, and even possibly accept only xhr, return false unless request.xhr? etc
event_id = params[:event_id]
html_partial = render_to_string 'shared/event', locals: { event_id: event_id }
respond_to do |format|
format.json { render json: { html: html_partial, success: true } }
end
end
$.ajax({
type: "POST",
url: window.location.pathname,
//...
});