【问题标题】:Div is not updated after selecting value on a dropdown list在下拉列表中选择值后 Div 未更新
【发布时间】:2017-09-29 15:01:03
【问题描述】:

我正在尝试在选择州和城市时显示图表。

城市下拉列表是根据在第一个下拉列表中选择的州来填充的。

问题是当我点击一个城市时没有显示图表,如果我更改选择也不会更新,我似乎无法找出问题所在。

我正在使用 ChartKick 显示一个饼图,其中包含控制器中的查询给出的值。

我的代码如下:

控制器/city_stats_controller.rb:

def city_stats
  @state = params[:state]
  @cities = City.where(:state => @state).select(:id, :display_name).uniq.order('display_name ASC')
  # @city_id = City.select('id').where(:state => params[:city_state]).where(:name => params[:city_name])
  @city_id = City.select('id').find_by_id(params[:city])

  dynamic_query = ActiveRecord::Base.send(:sanitize_sql_array, ['SELECT COALESCE(name) as name, count(*) FROM (SELECT name, regs.segment_id, count(*) FROM regs
    INNER JOIN segments ON regs.segment_id = segments.id
    WHERE regs.city_id = ?
    GROUP BY segment_id, name
    ORDER BY count(*) DESC) as tabe
    GROUP BY name;', @city_id])

  @spatial_ratio = ActiveRecord::Base.connection.select_all(dynamic_query)

  puts @city_id.inspect #I can see the value printed in the terminal
  puts @spatial_ratio.inspect #Same here, even after changing the selection

  respond_to do |format|
    format.json { render :json => @cities }
    format.js {
      render json: {
        html: render_to_string(
          partial: 'city_stats',
          locals: {
            city_id: @city_id,
            spatial_ratio: @spatial_ratio
          })
      }
    }
    format.html
  end
end

views/city_stats/city_stats.html.erb:

<div class="row">
    <label>State <span>:</span></label>
    <%= collection_select :city, :state, City.select(:state).uniq.order('state ASC'), :state, :state, {:prompt => 'Select a State'}, {id: 'city_state', multiple: false} %> 
    <label>City <span>:</span></label>
    <%= collection_select :city, :name, [], :name, :name, {:prompt => 'Select a City'}, {id: 'city_name', multiple: false} %>
</div>
<div id="cities">
 <!-- Here I render the cities list upon selecting a state-->
 <%= render :partial => 'city_stats', :object => @cities %>
</div>

<div id="stats">
</div>

<script type="text/javascript">

$(document).ready(function() {
 $("#city_state").on('change', function(){
  $.ajax({
   url: "/admin/city_stats",
   type: "GET",
   data: {state: $(this).val()},
   success: function(data) {
    $("#city_name").children().remove();
    // Create options and append to the list
    var listitems = []; 
    $.each(data,function(key, value) { 
      listitems += '<option value="' + value.id + '">' + value.display_name + '</option>';    
    });  
    $("#city_name").append(listitems);

    //console.log(listitems);

    $("#city_name").on('click', function(){
    $.ajax({
      url: "/admin/city_stats",
      type: "GET",
      data: {city: $(this).val()},
      success: function(data) {
        var content = $("#city_name").val()
        console.log(content);
        $('#stats').replaceWith("<%= j render(partial: 'city_stats') %>");
        return content;

      }
    })

  })
  }
})

});
});

在部分:views/city_stats/_city_stats.html.erb :

<%= pie_chart @spatial_ratio.rows %>

注意:如果我手动将控制器动态查询中的city_id替换为随机id,刷新页面时会显示对应城市的图表,但我不知道为什么它不能动态工作

【问题讨论】:

  • 您的城市点击事件是否有效? .我的意思是当你改变城市时,它会打服务器吗?
  • 嗨@krishnar 再次感谢您的回答!是的,当我更改城市时,我可以在终端以及浏览器控制台上看到新的 city_id
  • 抱歉回复晚了。你能给我的检查解决方案吗?

标签: javascript jquery ruby-on-rails chartkick


【解决方案1】:

1.更新您的 city_stats 方法,如下所示

def city_stats
  ...
  ...
  respond_to do |format|
   format.json  { render :json => @cities } 
   format.js
  end
end

2。使用以下代码创建 city_stats.js.erb 文件

$("#stats").html("<%= escape_javascript(pie_chart @spatial_ratio.rows) %>");

3.像这样改变你的 city_click 事件

  $("#city_name").on('click', function(){
    $.ajax({
      url: "/admin/city_stats",
      type: "GET",
      data: {city: $(this).val()},
      success: function(data) {
      }
    })
  });

这应该可以解决您的问题。如果有任何问题/疑问评论

【讨论】:

  • 非常感谢@krishnar 的帮助。它仍然没有解决我的问题,一旦我选择了一个城市,视图上什么也没有显示:/
  • @GeoSal 邀请我聊天。将讨论解决您的问题
  • 我认为我的声望不足以开始聊天,请邀请我吗?
  • 根据我们的讨论,只需将 dataType: "script" 添加到 ajax 请求中。再次感谢 Krishnar 的宝贵帮助!
【解决方案2】:
@city_id = City.select('id').find_by_id(params[:city])

此行不会返回数字。它返回一个模型实例,其中只加载了一个字段(id)。尝试将其更改为

@city_id = City.select('id').find_by_id(params[:city]).id

这会给你一个数字。

另外,正如我所见,在 $("#city_name").on('click') 的 AJAX 处理程序中,您实际上并没有使用生成的图表更新您的视图。

<%= j render(partial: 'city_stats') %>

此行仅在 html 页面的初始呈现时被评估一次(这就是为什么在手动设置 city_id 时一切正常的原因),因此在每个 AJAX 请求上,不会完全重新加载您的页面,您替换 @987654331 @内容相同。

顺便说一下,一旦你替换了$('#stats'),你下次访问它就不会完全重新渲染页面,因为它会从 DOM 中删除。请参阅 (replaceWith) 的参考资料。

我认为在 AJAX 的情况下,最好在 $('#stats') 容器上使用 .empty(),然后在其中使用 .append() 新图表。

这个想法是,如果你想在不重新加载页面的情况下更新图表,你应该使用来自服务器的新数据。

success: function(data) {

在您的情况下,它将位于 data 变量内。

我看到你的控制器中有这个:

format.js { 
  render json: { 
    html: render_to_string(
      partial: 'city_stats', 
      locals: { 
        city_id: @city_id,
        spatial_ratio: @spatial_ratio
    }) 
  }
}

所以你应该在你的处理程序中使用这些数据。可能是这样的:

success: function(data) {
    $('#stats').empty().append(data.html);
}

但是,我不确定它在当前实现中是否可以访问。我猜你每次发出 AJAX 请求时,都会以

format.json  { render :json => @cities }

因此,您应该返回 @cities 并在此处呈现部分内容,并在相关的成功回调中使用它们,或者以某种方式为每个请求单独响应。

关于代码的另一件事 - 在 $("#city_state") 的更改处理程序中绑定 $("#city_name") 的事件处理程序并不好,因为在每次更改 $("#city_state") 时,您都会为 $("#city_name") 添加相同的处理程序点击,然后每次单击此处理程序将被执行多次,因为它已被绑定。您可以在绑定之前使用.off 来防止这种情况发生,但也许值得进行一些重构。

【讨论】:

  • 感谢您的回答 Maksim,不幸的是,这并没有解决问题。我得到了 nil:NilClass 的未定义方法 `id'
  • 另外,当我打印查询时,我确实看到 city_id 作为数字
  • 这是我选择城市后终端上的查询: SELECT COALESCE(name) as name, count() FROM (SELECT name, regs.segment_id, count() FROM regs INNER JOIN 段 ON regs.segment_id = segments.id WHERE regs.city_id = 354 GROUP BY segment_id, name ORDER BY count(*) DESC) as tabe GROUP BY name;
  • Undefined method id for nil:NilClass 意味着 Rails 没有在数据库中找到记录。也许 params[:city] 有问题?
  • @GeoSal 关于同一个 json 中的多个对象 - 是的,您需要在不同的键 (like here) 下将它们添加到哈希中。关于绑定事件处理程序 - 如果可能,只需在另一个事件处理程序之外进行。如果您在为change 绑定处理程序时呈现了您的选择,为什么不在同一级别上为第二个选择绑定click 处理程序?如果它不适合您的情况,请检查其他选项:)
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2019-07-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
相关资源
最近更新 更多