knockout.js - knockout enlace de desplazamiento virtual
scroll dynamic-content (2)
Una solución simple sin usar un enlace personalizado:
Ejemplo de Fiddler: http://jsfiddle.net/adrienne/Y2WUN/
Margen:
<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 solución diferente que utiliza un enlace personalizado para desplazarse por la ventana completa del navegador:
http://figg-blog.tumblr.com/post/32733177516/infinite-scrolling-knocked-out .
Ejemplo de Fiddler: http://jsfiddle.net/8x4vG/2/
Usa el enlace así:
<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 un modelo de vista que se ve así:
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();
}
La implementación vinculante:
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
}
}
}
KOGrid utiliza el desplazamiento virtual para representar el contenido de forma dinámica. Estoy buscando algo así, pero más genérico, así que podría usarse para listas ul
, filas Bootstrap, lo que sea. Vi algo llamado giga-scroll , pero creo que ya no está. El Git está muerto.
¿Alguien ha visto un enlace personalizado para contenido dinámico mediante desplazamiento virtual?
Pensé que compartiría algunos otros scrollers que he encontrado ...