Rails 一个 Ajax 的问题 新手 网上都说的比较含糊所以来详细的问问。

so_zengtao · 2014年05月15日 · 最后由 hayate 回复于 2014年05月16日 · 2711 次阅读

1:先看路由吧:

match "/update_rooms" => "admin/lessons#update_rooms"

2:然后看看视图:

Venue <%= select_tag "venue_id", options_for_select(@venues.map { |item| [item.name, item.id] }), 
    :prompt => "Please select project", 
    :onchange => "update_versions_div(this.value)",
    :remote => true  %>

    <div id="roomsByVenue">
        <%= render :partial => 'roomsbyvenue', :locals => { :f => f} %>
    </div>

下面是_roomsbyvenue.html.erb

Room<%= f.select(:room_id, options_for_select(@rooms.map { |item| [item.name, item.id] })) %> </br>

3:js 的代码

function update_versions_div(venue_id) {
    jQuery.ajax({
        url: "/update_rooms",
        data: { "venue_id" :  venue_id },
        datatype: "html"
        success: function(data){
            jQuery("#roomsByVenue").html(data);
        }
    });
}

好了 问题来了。首先 在 application.html.erb 里面是可以知道任何在 assert/javascripts 里面的文件最后都是会被包含进来的。好了 我现在直接在 application.js 的最后加上了上述的 js 代码。然后到视图去操作 然后浏览器的调试会显示 见下图

我发现楼主的代码有几处问题 1 select_tag 不能 remote: true。 一般表单 按钮 链接 可以被 remote: true 原因是这些对象上都有一个网址, remote: true 才有意义。 比如:

link_to "New", new_blog_path, remote: true

但是我看出来楼主的意思是当 onchange的时候触发 remote: true 其实这个思路我感觉可以考虑搞个 GEM 出来支持这个行为, 但是 select_tag 也务必给个网址。

2 楼主报的错误 控制台报 update_versions_div 应该是因为楼主的 update_versions_div 是在一个命名空间内, 比如

# your.js
jQuery(function(){
  function update_versions_div(){}
});

楼主用 onchange 去调用这个命名空间内的方法,是访问不到的。 一般来说,现在的 web 程序不推荐使用 onchange 这个属性, 因为我们把这个叫内联 JS, 这个对 js 代码和 html 代码分离不太好,我们把 onchange 调 js 叫做耦合,把 onchange 这种属性删掉,而用纯 js 代码调用的方法叫解耦。 实现代码如下

select_tag
  'venue_id', 
  options_for_select(@venues.map { |item| [item.name, item.id] }), 
  prompt: 'Please select project',
  id: 'js-venue-select'

JS 中这么写

jQuery(function(){
  $('#js-venue-select').on('change', function(){
    jQuery.ajax({
        url: "/update_rooms",
        data: { "venue_id" :  venue_id },
        datatype: "html"
        success: function(data){
            jQuery("#roomsByVenue").html(data);
        }
    });
  });
});

js 会监事 select 的 onchange 事件,然后触发你想要的 ajax, 那么就不会出现未定义的方法这种问题了

检查一下 application.js 的其他内容是否包含进来了

#1 楼 @bydmm 非常感谢如此详细的解释 你也是武汉人么?

#2 楼 @palytoxin 这个默认的基本都是包含进来的 看了也没有什么问题的

#3 楼 @liwei78 前端太弱了。慢慢学习 多谢指点方向

#4 楼 @so_zengtao 没错 在武汉搞 rails 开发

#7 楼 @bydmm 卖萌网 请叫我萌弟弟。我刚转 rails 之前是弄 c++ 的 前端智商约为 0。 以后不会的还请多多指教

#8 楼 @so_zengtao 我的书签里居然有卖萌网。。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号