淘汰赛虚拟滚动绑定 [英] knockout virtual scrolling binding
问题描述
KOGrid 使用虚拟滚动来动态呈现内容.我正在寻找类似但更通用的东西,因此它可以用于 ul
列表、Bootstrap 行等.我看到了一个叫做 giga-scroll 的东西,但我认为它现在已经消失了.Git 已经死了.
是否有人通过虚拟滚动看到动态内容的自定义绑定?
不使用自定义绑定的简单解决方案:
Fiddler 示例:http://jsfiddle.net/adrienne/Y2WUN/
标记:
<span data-bind="text: items().length"></span><img src="http://rniemeyer.github.com/KnockMeOut/Images/loading.gif" data-bind="visible: pendingRequest"/><div id="main" data-bind="foreach: items, event: { scroll: scrolled }"><div data-bind="text: name"></div>
视图模型:
var viewModel = {项目:ko.observableArray([]),滚动:功能(数据,事件){var elem = event.target;if (elem.scrollTop > (elem.scrollHeight - elem.offsetHeight - 200)) {获取项目(20);}},最大 ID:0,待处理请求:ko.observable(false)};函数 getItems(cnt) {如果(!viewModel.pendingRequest()){//创建假数据传递给echo服务var 条目 = [];for (var i = 0; i < cnt; i++) {var id = viewModel.maxId++;条目.推送({身份证:身份证,名称:名称"+ ID});}viewModel.pendingRequest(true);$.ajax({类型:'POST',url: '/echo/json/',数据: {json: ko.toJSON(条目),延迟:.1},成功:功能(条目){ko.utils.arrayForEach(条目,函数(条目){viewModel.items.push(entry);});viewModel.pendingRequest(false);},错误:函数(){viewModel.pendingRequest(false);},数据类型:'json'});}}ko.applyBindings(viewModel);获取项目(20);
使用自定义绑定滚动整个浏览器窗口的不同解决方案:
http://figg-blog.tumblr.com/post/32733177516/infinite-scrolling-knocked-out.
Fiddler 示例:http://jsfiddle.net/8x4vG/2/
像这样使用绑定:
<div><span data-bind="text: $index()"></span><span data-bind="text: $data"></span>
<div data-bind="scroll: collection().length < 160, scrollOptions: { loadFunc: addSome, offset: 10 }">loading</div>
视图模型如下所示:
var viewModel = function(){this.collection = ko.observableArray([])var 迪士尼 = ["Mickey", "Donald", "Daffy", "Hewie", "Dewie", "Lewie"]var self = this;this.addSome = function(){for(var i = 0; i <40; i++){self.collection.push(迪士尼[Math.floor((Math.random()*6))])}}this.addSome();}
绑定实现:
ko.bindingHandlers.scroll = {更新:真实,初始化:函数(元素,valueAccessor,allBindingsAccessor){var self = thisself.updating = true;ko.utils.domNodeDisposal.addDisposeCallback(元素,函数(){$(window).off("scroll.ko.scrollHandler")自我更新 = 假});},更新:函数(元素,valueAccessor,allBindingsAccessor){var props = allBindingsAccessor().scrollOptionsvar offset = props.offset ?props.offset : "0"var loadFunc = props.loadFuncvar load = ko.utils.unwrapObservable(valueAccessor());var self = this;如果(加载){element.style.display = "";$(window).on("scroll.ko.scrollHandler", function(){if((($(document).height() - offset <= $(window).height() + $(window).scrollTop())){如果(自我更新){加载函数()self.updating = false;}}别的{self.updating = true;}});}别的{element.style.display = "无";$(window).off("scroll.ko.scrollHandler")自我更新 = 假}}}
KOGrid uses virtual scrolling to render content dynamically. I'm looking for something like that but more generic so it could be used for ul
lists, Bootstrap rows, whatever. I saw something called giga-scroll, but I think it's gone now. The Git is dead.
Has anyone seen a custom binding for dynamic content via virtual scrolling?
A simple solution without using a custom binding:
Fiddler Example: 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);
A different solution using a custom binding scrolling the entire browser window:
http://figg-blog.tumblr.com/post/32733177516/infinite-scrolling-knocked-out.
Fiddler example: http://jsfiddle.net/8x4vG/2/
Use the binding like so:
<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>
With a View Model looking something like this:
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();
}
The binding implementation:
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
}
}
}
这篇关于淘汰赛虚拟滚动绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!