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.
136 lines
3.9 KiB
136 lines
3.9 KiB
/** |
|
* 边滚动边加载的列表控件 |
|
* |
|
* Created by GUY on 2017/5/23. |
|
* @class BI.ListView |
|
* @extends BI.Widget |
|
*/ |
|
BI.ListView = BI.inherit(BI.Widget, { |
|
props: function () { |
|
return { |
|
baseCls: "bi-list-view", |
|
overscanHeight: 100, |
|
blockSize: 10, |
|
scrollTop: 0, |
|
el: {}, |
|
items: [], |
|
itemFormatter: function (item, index) { |
|
return item; |
|
}, |
|
}; |
|
}, |
|
|
|
init: function () { |
|
this.renderedIndex = -1; |
|
this.cache = {}; |
|
}, |
|
|
|
render: function () { |
|
var self = this, o = this.options; |
|
|
|
return { |
|
type: "bi.vertical", |
|
items: [BI.extend({ |
|
type: "bi.vertical", |
|
scrolly: false, |
|
ref: function (_ref) { |
|
self.container = _ref; |
|
}, |
|
}, o.el)], |
|
element: this, |
|
}; |
|
}, |
|
|
|
// mounted之后绑定事件 |
|
mounted: function () { |
|
var self = this, o = this.options; |
|
o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) { |
|
self.populate(newValue); |
|
}) : o.items; |
|
this._populate(); |
|
this.element.scroll(function (e) { |
|
o.scrollTop = self.element.scrollTop(); |
|
self._calculateBlocksToRender(); |
|
}); |
|
var lastWidth = this.element.width(), |
|
lastHeight = this.element.height(); |
|
BI.ResizeDetector.addResizeListener(this, function () { |
|
var width = self.element.width(), |
|
height = self.element.height(); |
|
if (width !== lastWidth || height !== lastHeight) { |
|
lastWidth = width; |
|
lastHeight = height; |
|
self._calculateBlocksToRender(); |
|
} |
|
}); |
|
}, |
|
|
|
_renderMoreIf: function () { |
|
var self = this, 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; |
|
var cnt = this.renderedIndex + 1; |
|
var lastHeight; |
|
|
|
function getElementHeight() { |
|
return self.container.element.height(); |
|
} |
|
|
|
lastHeight = getElementHeight(); |
|
while ((lastHeight) < minContentHeight && index < o.items.length) { |
|
var items = o.items.slice(index, index + o.blockSize); |
|
this.container.addItems(items.map(function (item, i) { |
|
return o.itemFormatter(item, index + i); |
|
}), this); |
|
var addedHeight = getElementHeight() - lastHeight; |
|
this.cache[cnt] = { |
|
index: index, |
|
scrollTop: lastHeight, |
|
height: addedHeight, |
|
}; |
|
this.renderedIndex = cnt; |
|
cnt++; |
|
index += o.blockSize; |
|
lastHeight = getElementHeight(); |
|
} |
|
}, |
|
|
|
_calculateBlocksToRender: function () { |
|
this._renderMoreIf(); |
|
}, |
|
|
|
_populate: function (items) { |
|
var o = this.options; |
|
if (items && this.options.items !== items) { |
|
this.options.items = items; |
|
} |
|
this._calculateBlocksToRender(); |
|
this.element.scrollTop(o.scrollTop); |
|
}, |
|
|
|
restore: function () { |
|
this.renderedIndex = -1; |
|
this.container.empty(); |
|
this.cache = {}; |
|
}, |
|
|
|
scrollTo: function (scrollTop) { |
|
this.options.scrollTop = scrollTop; |
|
this._calculateBlocksToRender(); |
|
this.element.scrollTop(scrollTop); |
|
}, |
|
|
|
populate: function (items) { |
|
if (items && this.options.items !== items) { |
|
this.restore(); |
|
} |
|
this._populate(items); |
|
}, |
|
|
|
destroyed: function () { |
|
this.restore(); |
|
}, |
|
}); |
|
BI.shortcut("bi.list_view", BI.ListView); |
|
|
|
|