简体   繁体   English

使用ajax进行Rails过滤并局部渲染

[英]Rails filtering with ajax and render partial

I'm trying to make filtering function with ajax and render partial. 我正在尝试使用ajax进行过滤并部分渲染。 The reason why I need these two is because there is an element I should not reload. 之所以需要这两个,是因为有一个我不应该重新加载的元素。 Because of this I'm trying to get a filtered data by ajax and render partial the filtered data. 因此,我试图通过ajax获取过滤的数据并部分渲染过滤的数据。 If there is anything I should let you know more, please tell me. 如果有什么我想让您了解更多,请告诉我。

Making index page work is fine. 使索引页工作正常。

controllers/item_controller.rb 控制器/ item_controller.rb

def index
    @items = Item.all
end

views/item/index.html.erb 意见/项目/ index.html.erb

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

views/item/item_list.erb 意见/项目/ item_list.erb

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

When I click a button, ajax is called and item/item_list.erb is reloaded. 当我单击一个按钮时,将调用ajax并重新加载item / item_list.erb。

controllers/item_controller.rb 控制器/ item_controller.rb

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

javascript 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');
    }
});

I can see the ajax called data in my console. 我可以在控制台中看到称为数据的ajax。 It took me several days but I really cannot find out a way to use the ajax called data as @items in the reloaded item/item_list.erb. 我花了几天的时间,但我真的找不到在重新加载的item / item_list.erb中将名为data的ajax用作@items的方法。 Thanks in advance for all comments. 预先感谢所有评论。

I think it may have to do with not passing in the data to your partial. 我认为这可能与不将data传递给您的部分data有关。 Try changing views/item/item_list.erb to 尝试将views / item / item_list.erb更改为

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

then call it in your view: 然后在您的视图中调用它:

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

then finally pass in data to the partial using JS: 然后最后使用JS将数据传递给部分对象:

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

Having said all that, I'd also recommend learning to use remote => true to simplify your js. 说了这么多,我还建议您学习使用remote => true来简化您的js。 I've found this guide straightforward: https://coderwall.com/p/kqb3xq/rails-4-how-to-partials-ajax-dead-easy 我发现本指南很简单: https//coderwall.com/p/kqb3xq/rails-4-how-to-partials-ajax-dead-easy

You can't. 你不能

The ERB interpolation (anything in ERB tags <% %> or <%= %> ) happens on the server before the the javascript is sent to the client. 在将javascript发送到客户端之前,服务器上发生了ERB插值(ERB标记<% %><%= %> )。 If your script is placed in app/assets/javascripts this done when the scripts are compiled at deploy time. 如果将脚本放置在app/assets/javascripts ,则在部署时编译脚本时会完成此操作。

The Ajax request happens later on the client. Ajax请求稍后在客户端上发生。

You either need to do the templating on the client side: 您要么需要在客户端进行模板处理:

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');
  }
)

Or use a js.erb template: 或使用js.erb模板:

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

You can also use Rails UJS to send the ajax request by adding the data-remote="true" to the form (usually done by adding remote: true to the form helper options). 您还可以使用Rails UJS通过向表单添加data-remote="true"来发送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 %>

You need to setup your controller to respond to the js format: 您需要设置控制器以响应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') %>");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM