2011-12-26 74 views
6

我已经看过分页https://gist.github.com/838460分页,并且这一切都似乎非常繁重,我正在寻找。轻量级无限滚动与backbone.js

我想做一个无限的滚动类型分页,我是新的骨干,所以也许我只是没有正确地解释它。

我以为我会做的是获得第一个集合,单击“下一个”按钮,并获得结果,并将其追加到原始集合并呈现新添加的项目。

所以我有这个在我的路由器我有一个指数函数

 
    if(!myApp.list){ 
     myApp.list = new myApp.collections.list; 
     myApp.list.page = 1; 
     } else { 
     myApp.list.page++; 
     } 
     myApp.list.url='/recipes?page='+myApp.list.page; 

     myApp.list.fetch({ 
      add: true, 
      success: function() { 
       new myApp.views.list({ collection: myApp.list}); 
      }, 
      error: function() { 
       new Error({ message: "Error loading documents." }); 
      } 
     }); 

这将创建集合,如果它存在的简化版,和如果它确实存在,请求下一个前增加了“页”列表中的项目。

所以我的问题的第一部分是,这种做事方式有什么不妥?看起来比我见过的其他解决方案简单得多。

问题#2似乎很荒谬,但我该如何触发'下一步'按钮来获得下一个列表?

在我看来,我有一个'下一步'按钮,但调用myApp.routers.list.index或myApp.views.list不会给我一个更新列表。

回答

3

如果存在路由器的声明,那么myApp.routers.list.index()不起作用是正常的,您需要调用路由器的实例。 有很多事情要说和我认为最好的解释是看代码的工作,如果这是你想要的,学习代码

我使用“更多”按钮创建了一个无限列表,使用您的代码在列表中添加模型。该演示是nodejitsu这里:http://infinite-scroll.eu01.aws.af.cm/

您就可以在我的要旨的完整代码(客户端和服务器)在GitHub上:https://gist.github.com/1522344我加了一个注释,以解释如何使用这些文件

+0

感谢通过所有的工作@Atinux去,我想我有一个更好的了解了。从你的回答中,我认为这样做没有错?它看起来比我见过的其他方法更清晰。 – pedalpete 2011-12-27 12:29:45

+0

我不认为这种方式有什么问题。如果有最佳做法做到这一点,请让我知道。在我看来,最简单的方法对代码和用户来说更好。 – Atinux 2011-12-27 14:45:35

+0

就这样,你知道,nodejitsu链接被破坏。 – Zach 2012-08-14 01:19:36

1

我创建Backbone.Collection,方便使用扩展:

_.extend Backbone.Collection.prototype, 
    options: 
    infinitescroll: 
     success: $.noop 
     error: $.noop 
     bufferPx: 40 
     scrollPx: 150 
     page: 
     current: 0 
     per: null 
     state: 
      isDuringAjax: false 
      isDone: false 
      isInvalid: false 
     loading: 
     wrapper: 'backbone-infinitescroll-wrapper' 
     loadingId: 'backbone-infinitescroll-loading' 
     loadingImg: 'loading.gif' 
     loadingMsg: '<em>Loading ...</em>' 
     finishedMsg: '<em>No more</em>' 
     msg: null 
     speed: 'fast' 

    infinitescroll: (options={})-> 
    # NOTE: coffeescript cannot deal with nested scope! 
    that = @ 

    _.extend(@options.infinitescroll, options.infinitescroll) if options.infinitescroll 

    infinitescroll_options = @options.infinitescroll 

    # where we want to place the load message in? 
    infinitescroll_options.loading.wrapper = $(infinitescroll_options.loading.wrapper) 
    if !infinitescroll_options.loading.msg and infinitescroll_options.loading.wrapper.size() > 0 
     infinitescroll_options.loading.msg = $('<div/>', { 
     id: infinitescroll_options.loading.loadingId 
     }).html('<img alt="'+$(infinitescroll_options.loading.loadingMsg).text()+'" src="' + infinitescroll_options.loading.loadingImg + '" /><div>' + infinitescroll_options.loading.loadingMsg + '</div>') 
     infinitescroll_options.loading.msg.appendTo(infinitescroll_options.loading.wrapper).hide() 
    else 
     infinitescroll_options.loading.msg = null 

    fetch_options = _.omit(options, 'infinitescroll') 
    infinitescroll_fetch =()=> 
     # mark the XHR request 
     infinitescroll_options.state.isDuringAjax = true 

     # increase page count 
     infinitescroll_options.page.current++ 

     payload = { 
     page: infinitescroll_options.page.current 
     } 
     payload['limit'] = infinitescroll_options.page.per if infinitescroll_options.page.per isnt null 

     _.extend(fetch_options, { 
     remove: false 
     data: payload 
     }) 

     if infinitescroll_options.loading.msg 
     # preload loading.loadingImg 
     (new Image()).src = infinitescroll_options.loading.loadingImg if infinitescroll_options.loading.loadingImg 

     infinitescroll_options.loading.msg.fadeIn infinitescroll_options.loading.speed,()-> 
      that.fetch(fetch_options) 
      .success (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isDone = true if _.size(data) is 0 

      infinitescroll_options.loading.msg.fadeOut infinitescroll_options.loading.speed,()-> 
       infinitescroll_options.success.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.success) 
       return 
      return 
      .error (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isInvalid = true 

      infinitescroll_options.loading.msg.fadeOut infinitescroll_options.loading.speed,()-> 
       infinitescroll_options.error.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.error) 
       return 
      return 
      return 

     else 
     that.fetch(fetch_options) 
     .success (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isDone = true if _.size(data) is 0 

      infinitescroll_options.success.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.success) 
      return 

     .error (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isInvalid = true 

      infinitescroll_options.error.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.error) 
      return 
     return 

    $(document).scroll()-> 
     $doc = $(document) 
     isNearBottom =()-> 
     bottomPx = 0 + $doc.height() - $doc.scrollTop() - $(window).height() 

     # if distance remaining in the scroll (including buffer) is less than expected? 
     (bottomPx - infinitescroll_options.bufferPx) < infinitescroll_options.scrollPx 

     return if infinitescroll_options.state.isDuringAjax || infinitescroll_options.state.isDone || infinitescroll_options.state.isInvalid || !isNearBottom() 

     infinitescroll_fetch() 
     return 


    infinitescroll_fetch() 
    return 

你可以看到执行情况https://gist.github.com/mcspring/7655861

+1

在某些时候,这个要点将会消失。我们更喜欢将代码直接放入您的答案中,就像我在这里所做的那样。这可以防止你的要求消失。 – 2013-11-26 16:46:08