fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
5.7 KiB

8 years ago
/**
* 表示当前对象
*
* Created by GUY on 2015/9/7.
* @class BI.VirtualList
* @extends BI.Widget
*/
BI.VirtualList = BI.inherit(BI.Widget, {
props: function () {
return {
8 years ago
baseCls: "bi-virtual-list",
overscanHeight: 100,
blockSize: 10,
scrollTop: 0,
items: []
8 years ago
};
},
8 years ago
init: function () {
this.renderedIndex = -1;
this.cache = {};
},
8 years ago
render: function () {
var self = this, o = this.options;
return {
8 years ago
type: "bi.vertical",
8 years ago
items: [{
type: "bi.layout",
ref: function () {
8 years ago
self.topBlank = this;
}
}, {
type: "bi.vertical",
scrolly: false,
ref: function () {
self.container = this;
}
}, {
type: "bi.layout",
ref: function () {
self.bottomBlank = this;
}
}],
element: this
8 years ago
}
},
mounted: function () {
8 years ago
var self = this, o = this.options;
this._populate();
this.element.scroll(function (e) {
o.scrollTop = self.element.scrollTop();
self._calculateBlocksToRender();
});
BI.ResizeDetector.addResizeListener(this, function () {
self._renderMoreIf();
});
},
_renderMoreIf: function () {
var o = this.options;
var height = this.element.height();
var minContentHeight = o.scrollTop + height + o.overscanHeight;
var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0,
cnt = this.renderedIndex + 1;
var lastHeight;
while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) {
var items = o.items.slice(index, index + o.blockSize);
this.container.addItems(items);
var addedHeight = this.container.element.height() - lastHeight;
this.cache[cnt] = {
index: index,
height: addedHeight
};
this.tree.set(cnt, addedHeight);
this.renderedIndex = cnt;
cnt++;
index += o.blockSize;
8 years ago
}
},
8 years ago
_calculateBlocksToRender: function () {
var o = this.options;
this._renderMoreIf();
// var height = this.element.height();
// var minContentHeightFrom = o.scrollTop - o.overscanHeight;
// var minContentHeightTo = o.scrollTop + height + o.overscanHeight;
// var start = this.tree.greatestLowerBound(minContentHeightFrom);
// var end = this.tree.leastUpperBound(minContentHeightTo);
// var summaryTopHeight = 0;
// this.topBlank.setHeight(0);
// this.bottomBlank.setHeight(0);
// var needDestroyed = [];
// for (var i = 0; i < start; i++) {
// var index = this.cache[i].index;
// summaryTopHeight += this.cache[i].height;
// if (!this.cache[i].destroyed) {
// for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
// needDestroyed.push(this.container._children[j]);
// this.container._children[j] = null;
// }
// this.cache[i].destroyed = true;
// // this.topBlank.setHeight(summaryTopHeight);
// }
// }
// summaryTopHeight = 0;
// for (var i = end + 1; i <= this.renderedIndex; i++) {
// var index = this.cache[i].index;
// summaryTopHeight += this.cache[i].height;
// if (!this.cache[i].destroyed) {
// for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
// needDestroyed.push(this.container._children[j]);
// this.container._children[j] = null;
// }
// this.cache[i].destroyed = true;
// // this.bottomBlank.setHeight(summaryTopHeight);
// }
// }
// var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment();
// var currentFragment = firstFragment;
// for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
// var index = this.cache[i].index;
// if (!this.cache[i].destroyed) {
// currentFragment = lastFragment;
// }
// if (this.cache[i].destroyed === true) {
// for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
// var w = this.container._children[j] = BI.createWidget(BI.extend({
// root: true
// }, BI.stripEL(o.items[j])));
// currentFragment.appendChild(w.element[0]);
// }
// this.cache[i].destroyed = false;
// }
// }
// this.container.element.prepend(firstFragment);
// this.container.element.append(lastFragment);
// BI.each(needDestroyed, function (i, child) {
// child && child._destroy();
// });
},
_populate: function () {
var o = this.options;
this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize));
this._calculateBlocksToRender();
this.element.scrollTop(o.scrollTop);
},
restore: function () {
this.renderedIndex = -1;
this.cache = {};
},
populate: function (items) {
},
destroyed: function () {
this.restore();
8 years ago
}
});
8 years ago
BI.shortcut('bi.virtual_list', BI.VirtualList);