新手问题 kaminari 做 api 的分页怎么做?

QueXuQ · 2014年05月15日 · 最后由 EvanYa 回复于 2021年10月20日 · 4551 次阅读

我的 api 结构:

{
  products: [
    {...}, {...}
  ],
  current_page: ?
  total_page: ?
}

我使用的 jbuilder,不知道怎么获得当前的页面和总共的页面呢?

其实这个可以直接看源码, paginate 这个方法肯定要调用 current_pagetotal_page ,直接看它实现就可以了。

products.current_page
products.total_page

API 比直接写 view 更灵活,不用关心怎么生成 html。我的一个例子:

meta = nil
# query 中调用了 page 方法才会有 current_page ,否则是没有的。
if products.respond_to?(:current_page)
  meta = {
    next_page: products.next_page,
    page: products.current_page,
    total: products.total_pages,
  }
end

json = { json: products, meta: meta }
render json

我自己用的懒人方法查 API:

Product.page().methods.grep /page/

#1 楼 @saiga Cool,感谢。

#2 楼 @darkbaby123 为什么使用meta这词?我看不少 api 都是把分页放到meta中,是有什么特别的原因吗?

顺便问一问,我使用了 ember 里你这个 model 的写法:http://ruby-china.org/topics/16915?page=2#reply90

如果涉及分页,根据你上面说的,然后我参考了:http://emberjs.com/guides/models/handling-metadata/

不知道应该如何获取:var meta = result.get("content.meta"),貌似这个写法行不通。

@QueXuQ 关于 meta,我是因为 JSON API 规范和 Ember Data 期待的数据结构里都用,才用的。而且我那个 model 写法是相当简单的,基本除了封装下 $.ajax 之外没干什么事情。你可以自己修改下 _findAll 方法去加上 meta 的逻辑。

举个栗子:

$.get("/api/tasks.json", params).then (payload) ->
  array = payload.tasks.map (obj) -> modelClass.create(obj)
  Em.set array, 'meta', payload.meta
  array

如果你是非常简单的情况,你甚至可以直接把 json 数据保存成 object 绑定到页面上,不一定需要自己写 model 封装。

#5 楼 @darkbaby123 感谢,已用。看来自己写 model 还是需要注意很多地方的。

app/views/shared/_pagination.json.jbuilder

json.pagination do
  json.current         collection.current_page
  json.previous        collection.prev_page
  json.next            collection.next_page
  json.limit           collection.limit_value
  json.total_pages     collection.total_pages
  json.total_count     collection.total_count

  json.data            collection
end

代码来源:https://gist.github.com/be9/6446051

需要 登录 后方可回复, 如果你还没有账号请 注册新账号