2011-12-26 34 views
6

Tôi đã xem xét phân trang trong xương sống https://gist.github.com/838460, và tất cả dường như rất nặng tay cho những gì tôi đang tìm kiếm.cuộn vô hạn nhẹ với backbone.js

Tôi muốn thực hiện phân trang loại cuộn vô hạn và tôi mới làm quen với xương sống, vì vậy có thể tôi không thực hiện chính xác nó.

những gì tôi nghĩ mình sẽ làm là lấy bộ sưu tập đầu tiên, nhấp vào nút 'tiếp theo' và nhận kết quả và chỉ nối thêm vào bộ sưu tập gốc và hiển thị các mục mới được thêm.

Vì vậy, tôi có điều này trong Router của tôi, tôi có một chức năng chỉ số

 
    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." }); 
      } 
     }); 

mà sẽ tạo ra bộ sưu tập nếu nó does't tồn tại, và nếu nó không tồn tại, thặng dư 'trang' trước khi yêu cầu tiếp theo các mục trong danh sách.

vì vậy phần đầu tiên của câu hỏi của tôi là, có điều gì sai trái với cách làm việc này không ?? Dường như đơn giản hơn nhiều so với các giải pháp khác mà tôi đã thấy.

Câu hỏi # 2 có vẻ vô lý, nhưng làm cách nào để kích hoạt nút 'tiếp theo' để nhận danh sách tiếp theo?

Theo quan điểm của tôi, tôi có nút 'tiếp theo', nhưng gọi myApp.routers.list.index hoặc myApp.views.list không cung cấp cho tôi danh sách được cập nhật.

Trả lời

3

Điều bình thường là myApp.routers.list.index() không hoạt động nếu có khai báo của Bộ định tuyến, bạn cần phải gọi phiên bản của bộ định tuyến. Có nhiều điều để nói và Tôi nghĩ rằng giải thích tốt nhất là xem mã hoạt động và nếu đó là điều bạn muốn, hãy tìm hiểu mã.

Tôi đã tạo danh sách vô hạn bằng nút "Thêm" để thêm mô hình trên danh sách bằng mã của bạn. Bản demo là trên nodejitsu đây: http://infinite-scroll.eu01.aws.af.cm/

Bạn có thể hiển thị các mã đầy đủ (client và server) trên ý chính của tôi trên GitHub: https://gist.github.com/1522344 (tôi thêm một nhận xét để giải thích cách sử dụng các tập tin)

+0

cảm ơn vì đã trải qua tất cả công việc đó @Atinux, tôi nghĩ giờ đây tôi đã hiểu rõ hơn. Và từ phản ứng của bạn, tôi cho rằng không có gì sai khi làm theo cách này? Nó có vẻ rõ ràng hơn nhiều so với các phương pháp khác tôi đã nhìn thấy. – pedalpete

+0

Tôi không nghĩ có gì đó sai trái theo cách này. Nếu có phương pháp hay nhất để thực hiện việc này, vui lòng cho tôi biết. Trong tâm trí của tôi, cách đơn giản nhất là tốt hơn, cho mã và cho người dùng. – Atinux

+0

Để bạn biết, liên kết nodejitsu bị hỏng. – Zach

1

Tôi đã tạo ra một mở rộng của Backbone.Collection để dễ dàng sử dụng:

_.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 

Bạn có thể thấy việc thực hiện tại https://gist.github.com/mcspring/7655861

+1

Tại một thời điểm nào đó, ý chí đó sẽ chết. Chúng tôi thích nếu bạn đặt mã trực tiếp vào câu trả lời của bạn, như tôi đã làm ở đây. Điều đó ngăn chặn điều này từ đi khi gist của bạn không. –

Các vấn đề liên quan