Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用will_paginate gem实现ajax分页_Ajax_Ruby On Rails 3_Will Paginate - Fatal编程技术网

如何使用will_paginate gem实现ajax分页

如何使用will_paginate gem实现ajax分页,ajax,ruby-on-rails-3,will-paginate,Ajax,Ruby On Rails 3,Will Paginate,我在我的ROR项目中使用will\u paginategem来显示页面中的记录 我希望使用ajax加载下一页而不重新加载整个页面 我在网上找到了一些例子,但它们不适合我 如何做到这一点?嘿,如果您想对产品进行分页,请尝试以下方法: app/controllers/products\u controller.rb def index @products = Product.paginate(page: params[:page], per_page: 10) end 视图/products/

我在我的
ROR
项目中使用
will\u paginate
gem来显示页面中的记录

我希望使用
ajax
加载下一页而不重新加载整个页面

我在网上找到了一些例子,但它们不适合我


如何做到这一点?

嘿,如果您想对产品进行分页,请尝试以下方法:

app/controllers/products\u controller.rb

def index
  @products = Product.paginate(page: params[:page], per_page: 10)
end
视图/products/index.html.erb

<div class = "sort_paginate_ajax"><%= render 'products' %></div>
因此,首先我们对所有产品的产品调用paginate方法,这里将根据
参数[:page]
设置偏移量,并通过
每页
选项设置限制。 此外,我们正在呈现
产品
部分,每次打开其他页面时都会呈现

在部分调用您想要的
@products
,然后将
分页
方法应用于
@products
,它还创建控制器中使用的
参数[:page]

现在,为了响应ajax请求,将
div
的内容呈现为类
sort\u paginate\u ajax
,并使用我们创建的部分

还要发出请求ajax请求,请在
div.sort\u paginate\u ajax
中的所有
a
标记的文档加载捕获脚本上执行,并返回false

现在将使用ajax请求调用页面

我希望这会对您有所帮助。

创建一个包含以下内容的新助手(例如app/helpers/will\u paginate\u 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
模块将为辅助对象分页
类WillPaginateJSLinkRendererWillPaginateHelper::WillPaginateJSLinkRenderer))
结束
结束
然后在您的视图中,将此标记用于ajax分页:

<%= js_will_paginate @recipes %>

请记住,分页链接将包括url的现有参数,您可以如下所示排除这些参数。这是标准的分页功能:

<%= js_will_paginate @recipes, :params => { :my_excluded_param => nil } %>
{:my_excluded_param=>nil}%>
希望这能解决你的问题

更新1:在我发布此解决方案的地方添加了对其工作原理的解释


更新2:我已经使它与远程:真实链接兼容,并将helper方法重命名为js\u will\u paginate

作为前面答案的补充

代码字符串:

$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){
替换为字符串:

$(".sort_paginate_ajax").on("click", ".pagination a", function(){

onclick事件仅应用于已存在的元素。因此,对于新出现的链接,需要从父级“.sort_paginate_ajax”到childs.pagination a”委派单击事件。您可以使用JQuery:

控制器:

def index
  @posts = Post.paginate(:page => params[:page])      

  respond_to do |format|
    format.html
    format.js
  end
end
然后在index.html.erb中:

<div id="post-content", posts: @posts >
  <%= j render 'post_content' %>
</div>
index.js.erb:

$('#post-content').html("<%= j render 'post_content' %>")

同样,在您的JS模板(index.JS.erb)中,当Ajax运行时,它会再次设置远程链接数据。

要继续从@Pierre的优秀答案重新创建助手,我看到了一些关于更新视图的后续问题(我最初遇到的问题)@Pierre接着指出,您需要创建一个js响应。以下是我在创建帮助器后所做的操作:

在my show.html.erb中

<div id="see-comments">
    <%= render @comments %>
</div>
<div id="pagination-comments">
    <%= js_will_paginate @comments %>
</div>

我创建了另一个名为show.js.erb的文件(show有两种格式)

//更新注释的步骤
$(“#见注释”).html(“”);
//更新分页链接的步骤
$(“#分页注释”).html(“”);

我想进一步阐述皮埃尔的答案

如果您将materialize sass与will_paginate_materialize一起使用,那么您将有一个初始值设定项来设置分页链接的样式

gem'will_paginate',“~>3.1.0'

gem'will_paginate-materialize',git:'https://github.com/mldoscar/will_paginate-materialize'分支:'主'

因此,为了使远程true在will_paginate_materialize初始值设定项呈现的链接上工作,我做了以下操作:

是否将\u分页\u helper.rb

module WillPaginateHelper
  class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
  end
  def js_will_paginate(collection, options = {})
    will_paginate(collection, options.merge(:renderer =>WillPaginateHelper::WillPaginateJSLinkRenderer))
  end
end
在我看来,我在will paginate链接中保留了相同的渲染器:


=will\u paginate results,renderer:MaterializePagination::Rails

很好,我发现第一次点击页面效果很好,但是在移动到下一个页面后,ajax调用没有应用于链接,它被称为html请求,这意味着,当第一次调用ajax并替换部分时,分页链接中不再附加任何实时事件,因此我在js.erb文件中添加了适当的js,以便在渲染新部分时将实时事件绑定到链接,效果非常好!请注意,从jQuery 1.7开始,live方法已被弃用,因此您必须将其替换为.on(),而不是.live()@rmagnum2002当您说您将正确的js添加到js.erb文件时,请提供一个示例,我遇到了一个问题,第一个下一个链接工作得很好,但是第二个请求在url中生成了一个链接,例如
/?\u=1399023289230&page=3
。我也将.live()改为.on(),谢谢you@Richlewis我已经在我的项目中使用过几次了。。我真的不记得我说的是什么。可能与.on()和.live()事件有关。我在几处看到了您的答案-在实现代码后,控制器肯定会被命中,结果会从数据库中提取。但这一页根本没有改变。我错过了什么?服务器日志显示“Rendered jobs/_jobstable.html.erb(80.7ms)”,但我屏幕上的实际页面没有呈现。浏览器正在生成jq
<%= will_paginate @posts %>
<% @posts.each do |post| %>
  <p><%= post.content %></p>
<% end %>
$(document).ready(function() {
  $('.pagination > a').attr('data-remote', 'true');
});
$('#post-content').html("<%= j render 'post_content' %>")
$('.pagination > a').attr('data-remote', 'true');
<div id="see-comments">
    <%= render @comments %>
</div>
<div id="pagination-comments">
    <%= js_will_paginate @comments %>
</div>
// to update comments    
$("#see-comments").html("<%= j render @comments %>");
// to update the pagination links
$("#pagination-comments").html('<%= js_will_paginate @comments %>');
module WillPaginateHelper
  class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
  end
  def js_will_paginate(collection, options = {})
    will_paginate(collection, options.merge(:renderer =>WillPaginateHelper::WillPaginateJSLinkRenderer))
  end
end
MaterializePagination::MaterializeRenderer.module_eval do
  def page_number(page)
    classes = ['waves-effect', ('active' if page == current_page)].join(' ')
    tag :li, link(page, page, :rel => rel_value(page)), class: classes
  end

  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

WillPaginate::ViewHelpers::LinkRenderer.class_eval do
  def symbolized_update(target, other, blacklist = nil)
    other.each_pair do |key, value|
      key = key.to_sym
      existing = target[key]
      next if blacklist && blacklist.include?(key)

      if value.respond_to?(:each_pair) and (existing.is_a?(Hash) or existing.nil?)
        symbolized_update(existing || (target[key] = {}), value)
      else
        if value.instance_variable_defined?(:@parameters)
          value = value.instance_variable_get(:@parameters)
        end
        target[key] = value
      end
    end
  end
end