打印

[Rails 常用插件简介]ajax_paginate

本帖已经被作者加入个人空间

[Rails 常用插件简介]ajax_paginate

(部分代码已经更新,请见5楼:http://www.ruby-lang.org.cn/foru ... fromuid=321#pid4598 )


其实这个并不是一个完整的插件,仅仅是个雏形,前因是由于Black的回帖:http://www.ruby-lang.org.cn/foru ... fromuid=321#pid4559 感觉Black是个很爱学习的小伙子,刚刚花了点时间做个简单的东西来实现Black需要的功能。其实这也是个简单的插件制作过程。


如果你不感兴趣,只是想使用,请直接转到 6楼:http://www.ruby-lang.org.cn/foru ... p;extra=page%3D1###

一:新建Project

php?name=rails" onclick="tagshow(event)" class="t_tag">rails ajax_paginate_demo


地球人都知道这个是干嘛的,不说了

二:安装will_paginate插件
本插件依赖will_paginate,请安装之
http://www.ruby-lang.org.cn/foru ... =985&highlight=


三:制作我们的ajax_paginate插件

ruby script/generate plugin ajax_paginate


并且在lib下新建ajax_paginate目录,目录如下图


修改init.rb

require 'ajax_paginate/view_helpers'

ActionView::Base.send :include, AjaxPaginate::ViewHelpers


如果你看过插件的源码,那么这个就不用说了。(就是让View中可以直接使用我们的AjaxPaginate::ViewHelpers中的方法)

will_paginate默认已经实现了分页的功能,我们要做的仅仅是增加ajax显示的效果,AjaxPaginate::ViewHelpers 从WillPaginate::ViewHelpers copy 过来的,
首先修改原来的will_paginate,我们从新命名为ajax_paginate

稍作修改

 def ajax_paginate(entries = @entries, options = {})
            total_pages = entries.page_count

            if total_pages > 1
               #保持原有的WillPaginate的options参数
                options = WillPaginate::ViewHelpers.pagination_options.merge options.symbolize_keys
                #....                      
                #修改为remote_page_link_or_span,下同                       
                        links << remote_page_link_or_span((n != page ? n : nil), 'current', n, param)
                    
                #...............
                # next and previous buttons
                links.unshift remote_page_link_or_span(entries.previous_page, 'disabled', options.delete(:prev_label), param)
                links.push    remote_page_link_or_span(entries.next_page,     'disabled', options.delete(:next_label), param)               
                #...............
            end
        end


增加remote_page_link_or_span

        def remote_page_link_or_span(page, span_class, text, param)
            unless page
                content_tag :span, text, :class => span_class
            else
                # page links should preserve GET parameters, so we merge params
                link_to_remote text, :url=>params.merge(param.to_sym => (page !=1 ? page : nil)), :method=>:get, :update=>''
            end
        end


OK,可以使用了:)
在View中直接使用

<%=ajax_paginate @users%>


即可看到效果了.

================================== 华丽的分割线=================================================
整个demo请从 6 楼下载

来个简单的应用来演示我们的插件是否生效,刚才我们已经新建了ajax_paginate_demo项目
1:修改database.yml

development:
  adapter: mysql
  database: ajax_paginate_demo
  username: root
  password: 
  host: localhost


2:建立数据库

create database ajax_paginate_demo


3:创建例子中的model,我们选用User

ruby script\generate scaffold_resource user name:string


仅仅包括一个字段,将附件中的001_create_users.rb覆盖你的数据,执行

rake db:migrate


将会导入几百条测试数据(这些数据来源于互联网,我随手检索了Authors List 发现这个网页的,我只是整理了下,做测试数据:http://www.classicreader.com/allauthor.htm

4:修改users_controller.rb

class UsersController < ApplicationController
    # GET /users
    # GET /users.xml
    def index
        @users = User.paginate :all, :page=>params[:page]||1
        respond_to do |format|
            format.html do
                unless params[:page].nil?
                    render :update do |page|
                        page.replace_html :page, :partial=>'list'
                    end
                end
            end
            format.xml  do
                render :xml => @users.to_xml
            end
        end
    end
end


5:修改index.html

<h1>Listing users</h1>
<div id="spinner_div" style="float:right">
    <%= image_tag 'spinner.gif', :id => 'spinner', :style => 'display: none' %>
</div>
<div id="page">
    <%=render :partial=>'list'%>
</div>


新增_list.rhtml

<table>
  <tr>
    <th>Name</th>
  </tr>

<% for user in @users %>
  <tr>
    <td><%=h user.name %></td>
  </tr>
<% end %>
</table>
<%=ajax_paginate @users%>


6:Ajax需要导入js,修改/app/views/layouts/users.rhtml导入js

  <%= javascript_include_tag :defaults%>


7:
还有什么呢?
........

没了,真的没了,测试一下看看结果如何:)满意不? 


任务还没完成,同志尚需努力!
================================== 华丽的分割线=================================================
更进一步讨论:

[ 本帖最后由 martin 于 2007-9-7 09:58 编辑 ]
本帖最近评分记录
  • blackanger R币 +5 辛苦了。。。感动ing 2007-9-7 10:38

TOP

内容已更新,请见5,6楼

[ 本帖最后由 martin 于 2007-9-7 09:55 编辑 ]

TOP

good job, :)
本帖最近评分记录
  • martin R币 +2 Thanks:) 2007-9-6 23:17

TOP

respond_to do |format|
    format.html do
      unless params[:page].nil?
       render :update do |page|
        page.replace_html :page, :partial=>'list'
       end
      end
    end
    format.xml do
      render :xml => @users.to_xml

这段代码可以带我详细解读下吗?很多高人写的都是这样的
谢谢
本帖最近评分记录
  • martin R币 +2 回帖工资:) 2007-9-7 10:00

TOP

Update

早上又花了几分钟把昨天的代码稍微该了下,将rails支持的ajax callback加进去,修改remote_page_link_or_span

        def remote_page_link_or_span(page, span_class, text, param, options)
            unless page
                content_tag :span, text, :class => span_class
            else
                link_to_remote text, @@default_options.merge(options).merge({:url=>params.merge(param.to_sym => (page !=1 ? page : nil))})
            end
        end


新增

@@default_options = {:method=>:get, :update=>''}


那么这样我们的页面上可以加上任何原来rails ajax的callback了,来几个例子
一:Confirm

<%=ajax_paginate @users,:confirm=>'Go?'%>


看到效果了吗,在提交的时候会确认

二:把昨天偷懒的代码抽取出来

<%=ajax_paginate @users, :before => %(Element.show('spinner')), :success => %(Element.hide('spinner'))'%>


三:如果你的controller不是用rjs做的,即不是

render :update do |page|
  page.replace_html :page, :partial=>'list'
end


你可以直接指定:update

<%=ajax_paginate @users,:update=>'page', :before => %(Element.show('spinner')), :success => %(Element.hide('spinner'))'%>


[ 本帖最后由 martin 于 2007-9-7 09:46 编辑 ]
本帖最近评分记录
  • drive2me R币 +3 Thanks. 2007-9-7 12:00

TOP

刚才我把代码已经放到google code上面了,如果你对上面不感兴趣,只是想用一下,请看这里
一:安装:

ruby script/plugin install  http://ajaxpaginate.googlecode.com/svn/trunk/ajax_paginate


二:使用
在View中直接使用

ajax_paginate @users[,其他ajax的参数,说明请见五楼和Rails 的AJAX_CALLBACK 文档]


Done!

三:最新的源码演示,请从这里获取

svn co http://ajaxpaginate.googlecode.com/svn/trunk/ajax_paginate_demo


不懂svn,直接下载该附件 (已更新
运行方法:
1:创建数据库
2:修改database.yml 使之正确
3:执行rake db:migrate 创建表结构并导入数据
4:运行测试

四:谁还有兴趣,可以接过去:)

[ 本帖最后由 martin 于 2007-9-7 12:46 编辑 ]
附件: 您所在的用户组无法下载或查看附件

TOP

引用:
原帖由 xnine 于 2007-9-7 08:14 发表
respond_to do |format|
    format.html do
      unless params[:page].nil?
       render :update do |page|
        page.replace_html :page, :part ...
推荐你先看下DHH的那篇 Discovering a world of Resources on Rails 视频(有PDF演讲稿),看完我们再讨论也会对你更有帮助一点:)

http://www.loudthinking.com/arc/2006_06.html

Enjoy

[ 本帖最后由 martin 于 2007-9-7 10:10 编辑 ]

TOP

辛苦了,martin。。。
感动ing。。。
本帖最近评分记录
  • martin R币 +2 回帖专用工资:) 2007-9-7 12:47

I.forget('you'){|something| something.remember.deepen}

TOP

挺好用,可是加了那个询问go是不是不太爽?
有个小bug,就是回不到第一页

[ 本帖最后由 blackanger 于 2007-9-7 11:19 编辑 ]
本帖最近评分记录
  • martin R币 +5 多谢测试:) 2007-9-7 12:48

I.forget('you'){|something| something.remember.deepen}

TOP

你这样一下把数据都取了出来,如果数据量大,性能上不行吧。。。

I.forget('you'){|something| something.remember.deepen}

TOP

引用:
原帖由 blackanger 于 2007-9-7 11:17 发表
挺好用,可是加了那个询问go是不是不太爽?
有个小bug,就是回不到第一页
加了go,仅仅是测试 :confirm效果而已,你可以把他去掉。第一页的问题我来看下

[ 本帖最后由 martin 于 2007-9-7 11:59 编辑 ]

TOP

引用:
原帖由 blackanger 于 2007-9-7 11:26 发表
你这样一下把数据都取了出来,如果数据量大,性能上不行吧。。。
取数据还是will_paginate的,你看controller,不会把把数据全取出来的。你没认真看代码:) 仅仅每页取20条记录而已,点下一页才会去取下20条数据。

TOP

我看到了,呵呵。。。明白了

I.forget('you'){|something| something.remember.deepen}

TOP

还是will_paginate的问题:
我用@products = Product.paginate :per_page =>20, :page=>params[:page]
这种和
@users = User.paginate :all, :page=>params[:page]||1
model里加
class<<self
   def per_page
    20
   end
  end
这两种用法有什么区别?

[ 本帖最后由 blackanger 于 2007-9-7 12:09 编辑 ]

I.forget('you'){|something| something.remember.deepen}

TOP

引用:
原帖由 blackanger 于 2007-9-7 12:08 发表
还是will_paginate的问题:
我用@products = Product.paginate :per_page =>20, :page=>params[:page]
这种和
@users = User.paginate :all, :page=>params[:page]||1
model里加
class
效果一样,

Product.paginate :per_page =>20


你指定了当前查询,每页20条记录,如果你不指定per_page他会去取

Product.per_page


这样也省的你每次都在查询的时候加上per_page了,这个是类函数

当然如果你什么这个也没有设,那么会用默认的per_page,可能是30.

[ 本帖最后由 martin 于 2007-9-7 12:28 编辑 ]
本帖最近评分记录

TOP

2008-11-22 17:15 Crawled by CCBot/1.0 (+http://www.commoncrawl.org/bot.html) @38.103.63.61