使用Rails控制器轻松替换AJAX HTML元素?

时间:2012-02-09 19:36:01

标签: javascript ruby-on-rails ajax

我希望能够像这样有一个ERB部分:

<ul id='things-index'>
  <% @things.each do |t| %>
    <li><%= t.name %></li>
  <% end %>
</ul>

能够在控制器中更新它,如下所示:

class ThingsController < ApplicationController
  def create
    @thing = Thing.new(params[:thing])
    @thing.save

    respond_to do |format|
      format.html
      format.js do
        @things = Thing.all
        page.replace('things-index')
      end
    end
  end
end

意味着JavaScript将作为响应发送,而我不必明确地编写js.erb模板,如下所示create.js.erb

$('#things-index').replaceWith('<%= escape_javascript(render("things/index")) %>')

可能有类似的东西,无论是内置于Rails还是作为gem提供,但如果有,我都不知道。

我认为理想情况下,它会通过JS重新呈现'index'动作并将更新发送到浏览器,所以看起来可能更像:

respond_to do |format|
  format.html
  format.js do
    render 'index'
  end
end

并知道要替换#things-index(或允许我明确指定它)。

更新

哎呀...当Prototype成为Rails的一部分时,显然有page.replace_html,但该功能已被.js.erb模板方法取代。这对我来说似乎不那么干(大量几乎相同的js.erb模板),所以如果有人有解决方案,我会很感激。

2 个答案:

答案 0 :(得分:4)

你可以将你想要的任何东西传递给你的js.erb,包括要替换的东西,以及什么。

$('<%= @id %>').replaceWith('<%= escape_javascript(render(@renderable)) %>')

注意即使在2012年,这也不是推荐的做事方式。这些天(2015年初)我会说,鉴于可用的优质客户端技术,它的建议更少。

答案 1 :(得分:2)

另一种解决方案是仅发回数据,以便客户端选择呈现:

respond_to do |format|
  format.html
  format.json do
   @things = Thing.all
   render :json => @things
  end
end

在客户端:

function updateList(data){
  var $item,
      $list = $('#things-index');

  $list.find('li').remove();

  $.each(data, function(i, item){
    $item = $('<li />').text(item.name);
    $list.append($item);
  });  
}

$.getJSON('/my/route.json', function(data){
  updateList(data);
});