2011-12-26 70 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