以前也没有接触过web开发,对web的分页并不是十分的了解.这次遇到分页的时候开始使用的是ror的paginate分页对象.发现的确很好用.使用起来简单,方便.关于paginate的使用这里就不说了,可以自己参照rails-documentation-1-2-1.chm很清楚.
有时候我们可能需要ajax的方法来显示分页对象,但是ror里面并没有封装一个ajax的版本.但是找到了一个pagination_links_each的help方法,利用这个函数我仿照page_links写了一个ajax 的方法page_links_remote
def page_links_remote(paginator,options={})
options[:name] ||= :page
options[:window_size] ||= 2
options[:always_show_anchors] ||= true
options[:link_to_current_page] ||= false
options[ :update] ||="mydiv"
pagination_links_each( paginator,options) do |n|
link_to_remote(n.to_s,options[ :update] ,:url=>{:page =>n})
end
end
只要把这个放在help下就可以在rhtml中通过调用
<
%= page_links_remote
%
>
就可以得到一个ajax方式的分页,他的参数在分页上和page_links一致.对于html的一些参数因为用不到自己没有做接口.需要的兄弟可以自己做.
很快的我发现我这个函数因为用link_to_remote做ajax调用不能胜任很多工作,比如在onclick的时候还要调用其他的JS代码.于是我修改后成为
def page_links_remote(paginator,js_code,options={})
options[:name] ||= :page
options[:window_size] ||= 2
options[:always_show_anchors] ||= true
options[:link_to_current_page] ||= false
options[ :update] ||="mydiv"
pagination_links_each( paginator,options) do |n|
#link_to_remote(n.to_s, :update => "mydiv2",:url=>{:page =>n})
html="
<
a
href
='#'
onclick
="new
Ajax.Updater('#{options[ :update]}', '/scaffold?page
=2',
{asynchronous:true, evalScripts:true}); #{js_code}; return false;"
>
"
return html
end
end
通过这种方式实现了可以onclick后面加其他的JS函数,这样就可以做到一个分页提交可以连前几也选择的东西一起提交的分页函数.(不对这种方式做详细阐述了,无非一个隐藏域而已)
但是很快问题便出现了.因为在我的项目中并没有使用active_record的多表关系,在遇到多边的时候我们采用的是 直接利用find_by_sql来执行SQL语句,因为ror的多表真的不快.
没有办法只能读了paginate的源码然后自己写一个了.
学习了源码后发现分页的思路主要是
1.取得总也数
2.通过分页对象修改查询条件和url
3.得到当前也数据
源码的一部分是头给我的,不好意思作为自己的东西拿出来说就不放出来了
但是有了上面三条的基本思路相信大家在对于不同的数据库也能做出自己的东西来.
不过还是用ror的paginate来说说好了
def count_collection_for_pagination(model, options)
model.count(:conditions => options[:conditions],
:joins => options[:join] || options[:joins],
:include => options[:include],
:select => options[:count])
end
首先ROR 的做法也是利用model.count来得到记录的总数.这里的modle是你传入的模型的名字对应的类调用,ror这里的方法我还不是很清楚,希望高手能指点下.(明白他用的和klass还有类的一些东西有关,但是不是很清楚)
利用下面这行代码,通过参数构造了分页对象
paginator = Paginator.new(self, count, options[:per_page], page)
利用下面这行代码,通过参数构造了当前页数据对象的ARRAY
collection = find_collection_for_pagination(klass, options, paginator)
def find_collection_for_pagination(model, options, paginator)
model.find(:all, :conditions => options[:conditions],
:order => options[:order_by] || options[:order],
:joins => options[:join] || options[:joins], :include => options[:include],
:select => options[:select], :limit => options[:per_page],
:offset => paginator.current.offset)
end
而在Paginator类里面的方法current_page,first_page...都是对页数的操作,在通过对help的方法的调用的时候生成一个URL的时候调用这些数字,在通过params[:page](当然可以换,我开心还能用params[:haha] ^_^)
def pagination_links(paginator, options={}, html_options={})
name = options[:name] || DEFAULT_OPTIONS[:name]
params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
pagination_links_each(paginator, options) do |n|
params[name] = n
link_to(n.to_s, params, html_options)
end
end
可以看到
link_to(n.to_s, params, html_options)
正好就是用了paginator生成的页数,通过n.to_s来做的连接.这样我们可以通过对这里的修改随意的创造自己的连接.在开头我的ajax也就是用了这种方式.
不得不说的就是,我们现在使用的active_record实际上仅仅对mysql有非常好的支持.在用oracle和其他的东西可能会出问题.而且可能很多时候我们更喜欢自己写的SQL语句超过active_record.这时候也可以通过以上的思路自己写一个分页对象满足自己的要求.
第一次写点东西,很可能牛头不对马嘴,希望大家见谅!