在JavaScript函数内部进行的Rails调用中使用JavaScript变量:Ajax在这里有什么帮助?

在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? %> <%

我依靠JavaScript对象定义的变量来更新(重新呈现)视图中的RubyonRails部分,但它不起作用。据我所知,它告诉我实现这一点的唯一可能方法是使用Ajax调用,但是我对这一点还不熟悉,不能完全理解为什么(考虑到在定义Rails命令之前JavaScript变量是可用的),也不知道我应该如何做

我的Rails视图有一个我想要的HTML位

<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,
  //...
});