将 AJAX 请求发送到控制器后,视图中的 JS (jQuery) 脚本无法运行

JS (jQuery) script in view do not operate after AJAX request is sent to controller

提问人:Dmitry 提问时间:8/3/2023 最后编辑:Dmitry 更新时间:8/3/2023 访问量:40

问:

视图中有jQuery脚本。首次打开页面时,脚本运行正常,并且数据从服务器放入以供查看,而无需 AJAX。当我从下拉列表中选择项目时,AJAX将其发送到控制器。控制器呈现 *.js.erb 视图和 *.html.erb 视图最后一次正确显示信息。从现在开始,脚本似乎从视图(从页面)中消失了。从下拉列表中选择项目没有任何反应。

但是,如果我将此脚本从*.html.erb视图复制到*.js.erb视图,则始终运行正常。 我无法理解这种行为。使用 AJAX,我只更改视图中一个 div 中的信息,并且不触及此视图的脚本部分......

values_controller.rb 中的操作


@values = Value.all

# This value initially generates here and next time goes from view with AJAX
@chosen_value = if params[:chosen_value].present?
              Value.find_by(label: params[:chosen_value])
            else
              'Just_label_of_my_value'
            end

respond_to do |format|
  format.js
  format.html { render 'value_shows' }
end

value_shows.html.erb


<div id="graphs">
  <div>
    <%= select("label", "label_value", @values.collect { |c| [ c[:name], c[:name] ] }, { prompt: '[Choose label]'}) %>
  </div>

  <%= @chosen_value %>
</div>

<script>
  $(function(){
    if (!$('#label_label_value').val()) {
      $('#label_label_value').val('<%= @chosen_value %>')
    }

    $("#label_label_value").change(function() { 
      $.ajax({ url: "/value_action", data: { 'chosen_value' : $('#label_label_value').val() }});
    });
  });
</script>

value_shows.js.erb

$("#graphs").html("<%= escape_javascript(render :partial => 'graphics') %>");

// If I copy script from view to here, everithing operates ok:
$(function(){
  if (!$('#label_label_value').val()) {
    $('#label_label_value').val('<%= @chosen_value %>')
  }

  $("#label_label_value").change(function() { 
    $.ajax({ url: "/value_shows", data: { 'chosen_value' : $('#label_label_value').val() }});
  });
});

_graphics.html.erb

<div>
  <%= select("label", "label_value", @values.collect { |c| [ c[:name], c[:name] ] }, { prompt: '[Choose label]'}) %>
</div>

<%= @chosen_value %>

更新

  1. 对不起,我错误地粘贴了视图和部分代码: 下拉列表位于 div 中,由 partial 更新。
  2. 我从更新的 div 中取出下拉列表,每次都开始正常运行。这样可以不断操作:

value_shows.html.erb

  <div>
    <%= select("label", "label_value", @values.collect { |c| [ c[:name], c[:name] ] }, { prompt: '[Choose label]'}) %>
  </div>


<div id="graphs">
  <%= @chosen_value %>
</div>

<script>
  $(function(){
    if (!$('#label_label_value').val()) {
      $('#label_label_value').val('<%= @chosen_value %>')
    }

    $("#label_label_value").change(function() { 
      $.ajax({ url: "/value_action", data: { 'chosen_value' : $('#label_label_value').val() }});
    });
  });
</script>

value_shows.js.erb

$("#graphs").html("<%= escape_javascript(render :partial => 'graphics') %>");

_graphics.html.erb

<%= @chosen_value %>

问题

  1. 据我了解,在部分替换 div 内容捆绑丢失后。为什么会这样?div 中元素的名称和 ID 保持不变。
  2. 要求下拉列表应位于更新的 div 内。我替换了这个脚本:
$("#label_label_value").change(function() { 
      $.ajax({ url: "/value_action", data: { 'chosen_value' : $('#label_label_value').val() }});
    });

有了这个:

 $("#graphs").on("change", "#label_label_value", function(){
    $.ajax({ url: "/value_action", data: { 'chosen_value' : $('#label_label_value').val() }});
  });

AJAX 请求现在每次都运行正常。 因此,请告知是否可以以相同的方式更改脚本的第一部分?

if (!$('#label_label_value').val()) {
  $('#label_label_value').val('<%= @chosen_value %>')
}

只找到一种工作方法:将脚本的第一部分添加到*.js部分。因为控制器的 rails 值只能在这里被捕获:

if (!$('#label_label_value').val()) {
  $('#label_label_value').val('<%= @chosen_value %>')
}
JavaScript jQuery Ruby-on-Rails

评论

0赞 Les Nightingill 8/3/2023
在哪里指定当收到对 Ajax 请求的响应时应该发生什么?我错过了吗?
0赞 Dmitry 8/3/2023
@LesNightingill,谢谢你的提问。我没有具体说明应该发生什么,因为它只能用 Rails 的控制器和视图来完成。JS 只需要将标签发送到控制器,而不必发送更多标签。也许我错了......更深入地描述逻辑:实际上,控制器为 gem 'apexcharts' 创建数据集,并在视图图表中根据下拉列表中选择的标签显示。但是,如果我删除所有图表逻辑并仅显示从控制器接收到的值 - everithing 将按照我的描述运行:仅在从下拉列表中选择它后一次。

答: 暂无答案