2017-09-15 133 views
1

我想用ajax做过滤函数并渲染部分。我需要这两个的原因是因为有一个元素我不应该重新加载。正因为如此,我试图通过Ajax获取过滤的数据,并呈现部分过滤的数据。如果有什么我应该让你知道更多,请告诉我。用ajax过滤Rails和渲染部分

使索引页工作正常。

控制器/ item_controller.rb

def index 
    @items = Item.all 
end 

的意见/项目/ index.html.erb

<div> 
    An element that should not be reloaded 
</div> 
<div id="item_list_wrapper"> 
    <%= render partial: 'item/item_list' %> 
</div> 

的意见/项目/ item_list.erb

<% @items.each do |i| %> 
    something 
<% end %> 

当我点击按钮,调用ajax并重载item/item_list.erb。

控制器/ item_controller.rb

def item_filter 
    filtered_items = Item.where(filtered item) 
    render json: filtered_items 
end 

的JavaScript

$.ajax({ 
    method: 'get', 
    url: '/item/filter', 
    dataType: 'json', 
    data: { 
     price: $('#price').val() 
    }, 
    success: function(data) { 
     console.log(data); 
     $("#item_list_wrapper").html("<%= escape_javascript(render partial: 'item/item_list') %>"); 
    }, 
    error: function(){ 
     alert('error'); 
    } 
}); 

我可以看到在我的控制台中的AJAX称为数据。这花了我好几天的时间,但我真的找不到在重载项目/ item_list.erb中使用称为数据的ajax作为@items的方法。预先感谢所有意见。

回答

0

你不行。

在将javascript发送到客户端之前,服务器上会发生ERB插值(ERB标记中的任何内容(<% %><%= %>))。如果脚本放置在app/assets/javascripts中,则在部署时编译脚本时完成此操作。

Ajax请求稍后在客户端发生。

你要么需要做客户端的模板:

var $template = $('<li></li>'); 
var promise = $.getJSON(
    url: '/item/filter', 
    data: { 
     price: $('#price').val() 
    }, 
    success: function(data) { 
    $.each(data, function(index, value) { 
     $("#item_list_wrapper").append($template.clone().text(value)); 
    }; 
    }, 
    error: function(){ 
    alert('error'); 
    } 
) 

或者使用js.erb模板:通过添加

var promise = $.ajax(
    url: '/item/filter', 
    data: { 
     price: $('#price').val() 
    }, 
    dataType: 'application/javascript', 
    error: function(){ 
    alert('error'); 
    } 
) 

您还可以使用Rails的UJS发送Ajax请求(通常通过将remote: true添加到表单助手选项中完成)。

# defaults to the js format 
# set "data-type" => :json to send JSON instead 
<%= form_tag('/item/filter', remote: true) %> 
    <%= number_field_tag(:price) %> 
    <%= submit_tag 'Filter items' %> 
<% end %> 

你需要设置你的控制器向js格式回应:

class ItemsController 
    def filter 
    # ... 
    respond_to do |format| 
     format.js 
    end 
    end 
end 

// app/items/views/filter.js.erb 
$("#item_list_wrapper").html("<%= escape_javascript(render partial: 'item/item_list') %>"); 
+0

您的路线也应该以复数形式命名为'/ items'。 – max

+0

我相信文件名应该是app/views/items/filter.js.erb – abax

+0

良好的捕捉@abax。 – max

0

我认为这可能与不通过data到你的部分。尝试改变看法/项目/ item_list.erb到

<% items.each do |i| %> something <% end %>

然后调用它在您的观点:

<%= render partial: 'item/item_list', locals: { items: @items } %>

然后终于在数据传递到使用JS部分:

$("#item_list_wrapper").html("<%= escape_javascript(render partial: 'item/item_list', locals: { items: data }) %>");

说了这么多,我还建议学习t o使用remote => true来简化你的js。我发现这本指南很简单:https://coderwall.com/p/kqb3xq/rails-4-how-to-partials-ajax-dead-easy

+0

感谢很多你既快速,完美的答案!我应该早点考虑编译时间! –