Как реализовать AJAX pagination с помощью will paginate gem
Я использую will_paginate
камень в мой для отображения записей на странице.
Я хочу, чтобы следующая страница была загружена без перезагрузки всей страницы с помощью ajax
.
Я нашел несколько примеров в интернете, но они не работают для меня.
как это сделать?
5 ответов
создайте нового помощника (ex. app / helpers / will_paginate_helper.rb) со следующим содержанием:
module WillPaginateHelper
class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
def prepare(collection, options, template)
options[:params] ||= {}
options[:params]['_'] = nil
super(collection, options, template)
end
protected
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = rel_value(target)
target = url(target)
end
@template.link_to(target, attributes.merge(remote: true)) do
text.to_s.html_safe
end
end
end
def js_will_paginate(collection, options = {})
will_paginate(collection, options.merge(:renderer => WillPaginateHelper::WillPaginateJSLinkRenderer))
end
end
тогда, на ваш взгляд, используйте этот тег для AJAX pagination:
<%= js_will_paginate @recipes %>
помните, что ссылки разбиения на страницы будут включать существующие параметры url-адреса, вы можете исключить их, как показано ниже. Это стандартная функция разбиения на страницы:
<%= js_will_paginate @recipes, :params => { :my_excluded_param => nil } %>
надеюсь, это решит вашу проблему.
обновление 1: добавлено объяснение того, как это работает для исходный вопрос где я разместил это решение.
обновление 2: Я сделал его Rails 4 совместимым с remote: true links и переименовал вспомогательный метод в js_will_paginate.
Эй, если вы хотите разбить продукты на страницы, попробуйте следующее:
app / контроллеры / products_controller.rb
def index
@products = Product.paginate(page: params[:page], per_page: 10)
end
просмотры / продукты / индекс.формат html.Эрб
<div class = "sort_paginate_ajax"><%= render 'products' %></div>
вид/продукты/_products.формат html.Эрб
<% @products.each do |product| %>
# your code
<% end %>
<%= will_paginate @products %>
просмотры / продукты / индекс.js.Эрб
$('.sort_paginate_ajax').html("<%= escape_javascript(render("products"))%>")
активы / javascripts / приложение.js
$(function() {
$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){
$.getScript(this.href);
return false;
});
});
Итак, сначала мы вызываем метод разбит на продукте для всех продуктов, здесь смещение будет установлен по к params[:page]
и предел будет установлен per_page
параметры.
Также мы оказываем products
частичный, который будет отображаться каждый раз, когда открывается другая страница.
в частичном вызове на @products
что вы хотите, а потом will_paginate
метод применяется на
@products
, он также создает params[:page]
что используется в контроллере.
теперь в ответ на ajax запрос рендеринга содержимого div
класса sort_paginate_ajax
С частичным, который мы создали.
также сделать запрос ajax запрос, на загрузку документа скрипт захвата всех a
теги div.sort_paginate_ajax
, и возвращать false.
теперь страницы будут вызываться с запросом ajax
я надеюсь, это поможет вам.
дополнительно к предыдущему ответу.
строку кода:
$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){
заменить строку:
$(".sort_paginate_ajax").on("click", ".pagination a", function(){
событие onclick применяется только к уже существующим элементам. Итак, для новых ссылок, нужно делегировать событие click от родителя ".sort_paginate_ajax "to childs".pagination a".
вы можете просто использовать JQuery:
:def index
@posts = Post.paginate(:page => params[:page])
respond_to do |format|
format.html
format.js
end
end
затем в индексе.формат html.Эрб:
<div id="post-content", posts: @posts >
<%= j render 'post_content' %>
</div>
частично ' _post_content.формат html.erb':
<%= will_paginate @posts %>
<% @posts.each do |post| %>
<p><%= post.content %></p>
<% end %>
пагинации.js:
$(document).ready(function() {
$('.pagination > a').attr('data-remote', 'true');
});
.js.Эрб:
$('#post-content').html("<%= j render 'post_content' %>")
добавьте
$('.pagination > a').attr('data-remote', 'true');
снова в вашем шаблоне JS (индекс.js.erb), поэтому он снова устанавливает ссылки data-remote при запуске Ajax.
чтобы следовать из @ Pierre's excellent answer re создание помощника, я видел некоторые последующие вопросы, касающиеся обновления представлений (проблема, которую я изначально имел). @Pierre следует за этой проблемой, заявив, что вам нужно создать ответ js. Вот что я сделал после создания помощника:
в моем шоу.формат html.Эрб
<div id="see-comments">
<%= render @comments %>
</div>
<div id="pagination-comments">
<%= js_will_paginate @comments %>
</div>
Я создал еще один файл под названием show.js.erb (так что два формата для шоу)
// to update comments
$("#see-comments").html("<%= j render @comments %>");
// to update the pagination links
$("#pagination-comments").html('<%= js_will_paginate @comments %>');