2013-07-19 11 views
18

KOGrid utilizza lo scorrimento virtuale per il rendering dinamico del contenuto. Sto cercando qualcosa di simile ma più generico, quindi potrebbe essere utilizzato per gli elenchi ul, le righe Bootstrap, qualunque sia. Ho visto qualcosa chiamato giga-scroll, ma penso che sia andato ora. Il Git è morto.vincolante con scorrimento virtuale a eliminazione diretta

Qualcuno ha visto un'associazione personalizzata per il contenuto dinamico tramite lo scorrimento virtuale?

+1

Che cosa si intende per lo scorrimento virtuale? – edhedges

+0

L'ho visto anche chiamato scrolling infinito. L'utente scorre fino alla parte inferiore della barra di scorrimento e quindi più elementi vengono inseriti dinamicamente nella pagina in modo che l'utente possa continuare a scorrere verso il basso. – Homer

+0

Ho lavorato su qualcosa, ma non dovrebbe essere così difficile da implementare in un binding personalizzato. – edhedges

risposta

28

Una soluzione semplice senza utilizzare un personalizzato vincolante:

Fiddler Esempio: http://jsfiddle.net/adrienne/Y2WUN/

Markup:

<div> 
    <span data-bind="text: items().length"></span> 
    <img src="http://rniemeyer.github.com/KnockMeOut/Images/loading.gif" data-bind="visible: pendingRequest" /> 
</div> 
<div id="main" data-bind="foreach: items, event: { scroll: scrolled }"> 
    <div data-bind="text: name"></div> 
</div> 

ViewModel:

var viewModel = { 
    items: ko.observableArray([]), 
    scrolled: function(data, event) { 
     var elem = event.target; 
     if (elem.scrollTop > (elem.scrollHeight - elem.offsetHeight - 200)) { 
      getItems(20); 
     } 
    }, 
    maxId: 0, 
    pendingRequest: ko.observable(false) 
}; 


function getItems(cnt) { 
    if (!viewModel.pendingRequest()) { 
     //create fake data to pass to echo service 
     var entries = []; 
     for (var i = 0; i < cnt; i++) { 
      var id = viewModel.maxId++; 
      entries.push({ 
       id: id, 
       name: "Name" + id 
      }); 
     } 

     viewModel.pendingRequest(true); 

     $.ajax({ 
      type: 'POST', 
      url: '/echo/json/', 
      data: { 
       json: ko.toJSON(entries), 
       delay: .1 
      }, 
      success: function(entries) { 
       ko.utils.arrayForEach(entries, function(entry) { 
        viewModel.items.push(entry); 
       }); 
       viewModel.pendingRequest(false); 
      }, 
      error: function() { 
       viewModel.pendingRequest(false); 
      }, 
      dataType: 'json' 
     }); 
    } 
} 

ko.applyBindings(viewModel); 

getItems(20); 

Una soluzione diversa che utilizza una associazione personalizzata che scorre l'intera finestra del browser:

http://figg-blog.tumblr.com/post/32733177516/infinite-scrolling-knocked-out.

Fiddler esempio: http://jsfiddle.net/8x4vG/2/

Utilizzare l'associazione in questo modo:

<div data-bind="foreach: collection"> 
    <div> 
    <span data-bind="text: $index()"></span> 
    <span data-bind="text: $data"></span> 
    </div> 
</div> 
<div data-bind="scroll: collection().length < 160, scrollOptions: { loadFunc: addSome, offset: 10 }">loading</div> 

Con una vista del modello cercando qualcosa di simile:

var viewModel = function(){    
    this.collection = ko.observableArray([]) 
    var disney = ["Mickey", "Donald", "Daffy", "Hewie", "Dewie", "Lewie"] 
    var self = this; 

    this.addSome = function(){ 
     for(var i = 0; i < 40; i++){ 
      self.collection.push(disney[Math.floor((Math.random()*6))]) 
     } 
    } 

    this.addSome(); 
} 

L'implementazione vincolante:

ko.bindingHandlers.scroll = { 

    updating: true, 

    init: function(element, valueAccessor, allBindingsAccessor) { 
     var self = this 
     self.updating = true; 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(window).off("scroll.ko.scrollHandler") 
      self.updating = false 
     }); 
    }, 

    update: function(element, valueAccessor, allBindingsAccessor){ 
    var props = allBindingsAccessor().scrollOptions 
    var offset = props.offset ? props.offset : "0" 
    var loadFunc = props.loadFunc 
    var load = ko.utils.unwrapObservable(valueAccessor()); 
    var self = this; 

    if(load){ 
     element.style.display = ""; 
     $(window).on("scroll.ko.scrollHandler", function(){ 
     if(($(document).height() - offset <= $(window).height() + $(window).scrollTop())){ 
      if(self.updating){ 
      loadFunc() 
      self.updating = false; 
      } 
     } 
     else{ 
      self.updating = true; 
     } 
     }); 
    } 
    else{ 
     element.style.display = "none"; 
     $(window).off("scroll.ko.scrollHandler") 
     self.updating = false 
    } 
    } 
} 
+0

Hmmm ... 'evento: {scroll: scrolled}' non sembra sparare a tutto .. – Marcel

Problemi correlati