带有backbone.js的轻量级无限滚动

时间:2011-12-26 20:12:09

标签: backbone.js

我看过骨干https://gist.github.com/838460中的分页,对于我正在寻找的东西,这一切看起来都非常沉重。

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

我认为我会做的是获取第一个集合,单击“下一步”按钮,然后获取结果并将其附加到原始集合并渲染新添加的项目。

所以我在我的路由器中有这个,我有一个索引函数

    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并没有给我一个更新列表。

7 个答案:

答案 0 :(得分:3)

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

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

您可以在GitHub上显示我的要点上的完整代码(客户端和服务器):https://gist.github.com/1522344我添加了一条评论来解释如何使用文件

答案 1 :(得分:2)

这是一个轻量级的实现https://github.com/joneath/infiniScroll.js

答案 2 :(得分:1)

答案 3 :(得分: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

查看实施情况

答案 4 :(得分:0)

答案 5 :(得分:0)

答案 6 :(得分:0)

查看Backbone Infinite Scroll

它基于单一模型和单一视图。

Here is a demo site