【问题标题】:knockout virtual scrolling binding淘汰赛虚拟滚动绑定
【发布时间】:2013-07-18 21:04:53
【问题描述】:

KOGrid 使用虚拟滚动来动态呈现内容。我正在寻找类似但更通用的东西,因此它可以用于ul 列表、引导行等。我看到了一个名为giga-scroll 的东西,但我认为它现在已经消失了。 Git 已经死了。

有人见过通过虚拟滚动对动态内容进行自定义绑定吗?

【问题讨论】:

  • 虚拟滚动是什么意思?
  • 我也见过它叫做无限滚动。用户滚动到滚动条的底部,然后更多的项目被动态插入到页面中,以便用户可以继续向下滚动。
  • 我一直在做一些事情,但在自定义绑定中实现自己应该不难。
  • 要分享吗?
  • 它不完整,但是您希望将哪种数据传递给绑定?你基本上需要做两件主要的事情。显示数据数组的子集(这可以作为 observableArray 的计算 observable 处理)。第二部分涉及处理滚动元素上的滚动事件以及检测/处理滚动区域的底部。

标签: knockout.js scroll dynamic-content


【解决方案1】:

【讨论】:

  • 正是我想要的。感谢分享!
【解决方案2】:

不使用自定义绑定的简单解决方案:

提琴手示例:http://jsfiddle.net/adrienne/Y2WUN/

标记:

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

视图模型:

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);

使用自定义绑定滚动整个浏览器窗口的不同解决方案:

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

提琴手示例:http://jsfiddle.net/8x4vG/2/

像这样使用绑定:

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

视图模型看起来像这样:

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(); 
}

绑定实现:

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
    }
  }
 }

【讨论】:

    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2013-10-31
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    相关资源
    最近更新 更多