Browse Source

KERNEL-13841 refactor:base文件es6化与import引入适配

es6
Joker.Wang-王顺 2 years ago
parent
commit
3c98a6b4b8
  1. 305
      src/base/grid/grid.js
  2. 42
      src/base/index.js
  3. 6
      src/base/layer/layer.drawer.js
  4. 9
      src/base/layer/layer.popover.js
  5. 14
      src/base/layer/layer.popup.js
  6. 7
      src/base/layer/layer.searcher.js
  7. 250
      src/base/list/listview.js
  8. 353
      src/base/list/virtualgrouplist.js
  9. 357
      src/base/list/virtuallist.js
  10. 151
      src/base/pager/pager.js
  11. 7
      src/base/single/a/a.js
  12. 5
      src/base/single/tip/0.tip.js
  13. 6
      src/base/single/tip/tip.toast.js
  14. 7
      src/base/single/tip/tip.tooltip.js

305
src/base/grid/grid.js

@ -5,9 +5,11 @@
* @class BI.GridView
* @extends BI.Widget
*/
BI.GridView = BI.inherit(BI.Widget, {
_defaultConfig: function () {
return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), {
import { Widget, shortcut } from "../../core";
@shortcut()
export default class GridView extends Widget {
_defaultConfig() {
return BI.extend(super._defaultConfig(arguments), {
baseCls: "bi-grid-view",
// width: 400, //必设
// height: 300, //必设
@ -28,50 +30,54 @@ BI.GridView = BI.inherit(BI.Widget, {
scrollLeft: 0,
scrollTop: 0,
items: [],
itemFormatter: function (item, row, col) {
itemFormatter: (item, row, col)=> {
return item;
},
});
},
}
render: function () {
var self = this, o = this.options;
static xtype = "bi.grid_view";
static EVENT_SCROLL = "EVENT_SCROLL";
render() {
const o = this.options;
const { overflowX, overflowY, el } = this.options;
this.renderedCells = [];
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
this._debounceRelease = BI.debounce(function () {
self._scrollLock = false;
this._debounceRelease = BI.debounce(()=> {
this._scrollLock = false;
}, 1000 / 60);
this.container = BI._lazyCreateWidget({
type: "bi.absolute",
});
this.element.scroll(function () {
if (self._scrollLock === true) {
this.element.scroll(()=> {
if (this._scrollLock === true) {
return;
}
o.scrollLeft = self.element.scrollLeft();
o.scrollTop = self.element.scrollTop();
self._calculateChildrenToRender();
self.fireEvent(BI.GridView.EVENT_SCROLL, {
o.scrollLeft = this.element.scrollLeft();
o.scrollTop = this.element.scrollTop();
this._calculateChildrenToRender();
this.fireEvent(GridView.EVENT_SCROLL, {
scrollLeft: o.scrollLeft,
scrollTop: o.scrollTop,
});
});
// 兼容一下
var scrollable = o.scrollable, scrollx = o.scrollx, scrolly = o.scrolly;
if (o.overflowX === false) {
if (o.overflowY === false) {
let scrollable = o.scrollable, scrollx = o.scrollx, scrolly = o.scrolly;
if (overflowX === false) {
if (overflowY === false) {
scrollable = false;
} else {
scrollable = "y";
}
} else {
if (o.overflowY === false) {
if (overflowY === false) {
scrollable = "x";
}
}
BI._lazyCreateWidget(o.el, {
BI._lazyCreateWidget(el, {
type: "bi.vertical",
element: this,
scrollable: scrollable,
@ -79,111 +85,113 @@ BI.GridView = BI.inherit(BI.Widget, {
scrollx: scrollx,
items: [this.container],
});
o.items = BI.isFunction(o.items) ? this.__watch(o.items, function (context, newValue) {
self.populate(newValue);
o.items = BI.isFunction(o.items) ? this.__watch(o.items, (context, newValue)=> {
this.populate(newValue);
}) : o.items;
if (o.items.length > 0) {
this._calculateSizeAndPositionData();
this._populate();
}
},
}
// mounted之后绑定事件
mounted: function () {
var o = this.options;
if (o.scrollLeft !== 0 || o.scrollTop !== 0) {
this.element.scrollTop(o.scrollTop);
this.element.scrollLeft(o.scrollLeft);
mounted() {
const { scrollLeft, scrollTop } = this.options;
if (scrollLeft !== 0 || scrollTop !== 0) {
this.element.scrollTop(scrollTop);
this.element.scrollLeft(scrollLeft);
}
},
}
destroyed: function () {
BI.each(this.renderedCells, function(i, cell) {
destroyed() {
BI.each(this.renderedCells, (i, cell)=> {
cell.el._destroy();
})
},
}
_calculateSizeAndPositionData: function () {
var o = this.options;
_calculateSizeAndPositionData() {
const { columnCount, items, rowCount, columnWidthGetter, estimatedColumnSize, rowHeightGetter, estimatedRowSize } = this.options;
this.rowCount = 0;
this.columnCount = 0;
if (BI.isNumber(o.columnCount)) {
this.columnCount = o.columnCount;
} else if (o.items.length > 0) {
this.columnCount = o.items[0].length;
if (BI.isNumber(columnCount)) {
this.columnCount = columnCount;
} else if (items.length > 0) {
this.columnCount = items[0].length;
}
if (BI.isNumber(o.rowCount)) {
this.rowCount = o.rowCount;
if (BI.isNumber(rowCount)) {
this.rowCount = rowCount;
} else {
this.rowCount = o.items.length;
this.rowCount = items.length;
}
this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, o.columnWidthGetter, o.estimatedColumnSize);
this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, o.rowHeightGetter, o.estimatedRowSize);
},
this._columnSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.columnCount, columnWidthGetter, estimatedColumnSize);
this._rowSizeAndPositionManager = new BI.ScalingCellSizeAndPositionManager(this.rowCount, rowHeightGetter, estimatedRowSize);
}
_getOverscanIndices: function (cellCount, overscanCellsCount, startIndex, stopIndex) {
_getOverscanIndices(cellCount, overscanCellsCount, startIndex, stopIndex) {
return {
overscanStartIndex: Math.max(0, startIndex - overscanCellsCount),
overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount),
};
},
}
_calculateChildrenToRender() {
const o = this.options;
_calculateChildrenToRender: function () {
var self = this, o = this.options;
const { itemFormatter, items } = this.options;
var width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
const width = o.width, height = o.height, scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft()),
scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop()),
overscanColumnCount = o.overscanColumnCount, overscanRowCount = o.overscanRowCount;
if (height > 0 && width > 0) {
var visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
var visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
const visibleColumnIndices = this._columnSizeAndPositionManager.getVisibleCellRange(width, scrollLeft);
const visibleRowIndices = this._rowSizeAndPositionManager.getVisibleCellRange(height, scrollTop);
var renderedCells = [], renderedKeys = {}, renderedWidgets = {};
const renderedCells = [], renderedKeys = {}, renderedWidgets = {};
let minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0;
// 没有可见的单元格就干掉所有渲染过的
if (!BI.isEmpty(visibleColumnIndices) && !BI.isEmpty(visibleRowIndices)) {
var horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft);
var verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
const horizontalOffsetAdjustment = this._columnSizeAndPositionManager.getOffsetAdjustment(width, scrollLeft);
const verticalOffsetAdjustment = this._rowSizeAndPositionManager.getOffsetAdjustment(height, scrollTop);
this._renderedColumnStartIndex = visibleColumnIndices.start;
this._renderedColumnStopIndex = visibleColumnIndices.stop;
this._renderedRowStartIndex = visibleRowIndices.start;
this._renderedRowStopIndex = visibleRowIndices.stop;
var overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex);
const overscanColumnIndices = this._getOverscanIndices(this.columnCount, overscanColumnCount, this._renderedColumnStartIndex, this._renderedColumnStopIndex);
var overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex);
const overscanRowIndices = this._getOverscanIndices(this.rowCount, overscanRowCount, this._renderedRowStartIndex, this._renderedRowStopIndex);
var columnStartIndex = overscanColumnIndices.overscanStartIndex;
var columnStopIndex = overscanColumnIndices.overscanStopIndex;
var rowStartIndex = overscanRowIndices.overscanStartIndex;
var rowStopIndex = overscanRowIndices.overscanStopIndex;
const columnStartIndex = overscanColumnIndices.overscanStartIndex;
const columnStopIndex = overscanColumnIndices.overscanStopIndex;
const rowStartIndex = overscanRowIndices.overscanStartIndex;
const rowStopIndex = overscanRowIndices.overscanStopIndex;
// 算区间size
var minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex);
var minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex);
var maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex);
var maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex);
var top = minRowDatum.offset + verticalOffsetAdjustment;
var left = minColumnDatum.offset + horizontalOffsetAdjustment;
var bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
var right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size;
const minRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStartIndex);
const minColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStartIndex);
const maxRowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowStopIndex);
const maxColumnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnStopIndex);
const top = minRowDatum.offset + verticalOffsetAdjustment;
const left = minColumnDatum.offset + horizontalOffsetAdjustment;
const bottom = maxRowDatum.offset + verticalOffsetAdjustment + maxRowDatum.size;
const right = maxColumnDatum.offset + horizontalOffsetAdjustment + maxColumnDatum.size;
// 如果滚动的区间并没有超出渲染的范围
if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
return;
}
var minX = this._getMaxScrollLeft(), minY = this._getMaxScrollTop(), maxX = 0, maxY = 0;
var count = 0;
for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
var rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
let count = 0;
for (let rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
const rowDatum = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);
for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
var key = rowIndex + "-" + columnIndex;
var columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex);
for (let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
const key = rowIndex + "-" + columnIndex;
const columnDatum = this._columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex);
var index = this.renderedKeys[key] && this.renderedKeys[key][2];
var child;
const index = this.renderedKeys[key] && this.renderedKeys[key][2];
let child;
if (index >= 0) {
this.renderedCells[index].el.setWidth(columnDatum.size);
this.renderedCells[index].el.setHeight(rowDatum.size);
@ -193,7 +201,7 @@ BI.GridView = BI.inherit(BI.Widget, {
child = this.renderedCells[index].el;
renderedCells.push(this.renderedCells[index]);
} else {
var item = o.itemFormatter(o.items[rowIndex][columnIndex], rowIndex, columnIndex);
const item = itemFormatter(items[rowIndex][columnIndex], rowIndex, columnIndex);
child = BI._lazyCreateWidget(BI.extend({
type: "bi.label",
width: columnDatum.size,
@ -226,9 +234,9 @@ BI.GridView = BI.inherit(BI.Widget, {
}
}
// 已存在的, 需要添加的和需要删除的
var existSet = {}, addSet = {}, deleteArray = [];
BI.each(renderedKeys, function (i, key) {
if (self.renderedKeys[i]) {
const existSet = {}, addSet = {}, deleteArray = [];
BI.each(renderedKeys, (i, key)=> {
if (this.renderedKeys[i]) {
existSet[i] = key;
} else {
addSet[i] = key;
@ -243,11 +251,11 @@ BI.GridView = BI.inherit(BI.Widget, {
}
deleteArray.push(key[2]);
});
BI.each(deleteArray, function (i, index) {
BI.each(deleteArray, (i, index)=> {
// 性能优化,不调用destroy方法防止触发destroy事件
self.renderedCells[index].el._destroy();
this.renderedCells[index].el._destroy();
});
var addedItems = [];
const addedItems = [];
BI.each(addSet, function (index, key) {
addedItems.push(renderedCells[key[2]]);
});
@ -260,13 +268,12 @@ BI.GridView = BI.inherit(BI.Widget, {
this.renderedKeys = renderedKeys;
this.renderRange = { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
}
},
}
_isOverflowX: function () {
var o = this.options;
_isOverflowX() {
const { scrollable, scrollx, overflowX } = this.options;
// 兼容一下
var scrollable = o.scrollable, scrollx = o.scrollx;
if (o.overflowX === false) {
if (overflowX === false) {
return false;
}
if (scrollx) {
@ -276,13 +283,13 @@ BI.GridView = BI.inherit(BI.Widget, {
return true;
}
return false;
},
}
_isOverflowY: function () {
var o = this.options;
_isOverflowY() {
const { scrollable, scrolly, overflowX } = this.options;
// 兼容一下
var scrollable = o.scrollable, scrolly = o.scrolly;
if (o.overflowX === false) {
// var scrollable = o.scrollable, scrolly = o.scrolly;
if (overflowX === false) {
return false;
}
if (scrolly) {
@ -292,26 +299,26 @@ BI.GridView = BI.inherit(BI.Widget, {
return true;
}
return false;
},
}
_getMaxScrollLeft: function () {
_getMaxScrollLeft() {
return Math.max(0, this._getContainerWidth() - this.options.width + (this._isOverflowX() ? BI.DOM.getScrollWidth() : 0));
},
}
_getMaxScrollTop: function () {
_getMaxScrollTop() {
return Math.max(0, this._getContainerHeight() - this.options.height + (this._isOverflowY() ? BI.DOM.getScrollWidth() : 0));
},
}
_getContainerWidth: function () {
_getContainerWidth() {
return this.columnCount * this.options.estimatedColumnSize;
},
}
_getContainerHeight: function () {
_getContainerHeight() {
return this.rowCount * this.options.estimatedRowSize;
},
}
_populate: function (items) {
var o = this.options;
_populate(items) {
const { scrollTop, scrollLeft } = this.options;
this._reRange();
if (items && items !== this.options.items) {
this.options.items = items;
@ -323,14 +330,14 @@ BI.GridView = BI.inherit(BI.Widget, {
// 元素未挂载时不能设置scrollTop
this._debounceRelease();
try {
this.element.scrollTop(o.scrollTop);
this.element.scrollLeft(o.scrollLeft);
this.element.scrollTop(scrollTop);
this.element.scrollLeft(scrollLeft);
} catch (e) {
}
this._calculateChildrenToRender();
},
}
setScrollLeft: function (scrollLeft) {
setScrollLeft(scrollLeft) {
if (this.options.scrollLeft === scrollLeft) {
return;
}
@ -339,9 +346,9 @@ BI.GridView = BI.inherit(BI.Widget, {
this._debounceRelease();
this.element.scrollLeft(this.options.scrollLeft);
this._calculateChildrenToRender();
},
}
setScrollTop: function (scrollTop) {
setScrollTop(scrollTop) {
if (this.options.scrollTop === scrollTop) {
return;
}
@ -350,72 +357,68 @@ BI.GridView = BI.inherit(BI.Widget, {
this._debounceRelease();
this.element.scrollTop(this.options.scrollTop);
this._calculateChildrenToRender();
},
}
setColumnCount: function (columnCount) {
setColumnCount(columnCount) {
this.options.columnCount = columnCount;
},
}
setRowCount: function (rowCount) {
setRowCount(rowCount) {
this.options.rowCount = rowCount;
},
}
setOverflowX: function (b) {
var self = this;
setOverflowX(b) {
if (this.options.overflowX !== !!b) {
this.options.overflowX = !!b;
BI.nextTick(function () {
self.element.css({ overflowX: b ? "auto" : "hidden" });
BI.nextTick(()=> {
this.element.css({ overflowX: b ? "auto" : "hidden" });
});
}
},
}
setOverflowY: function (b) {
var self = this;
setOverflowY(b) {
if (this.options.overflowY !== !!b) {
this.options.overflowY = !!b;
BI.nextTick(function () {
self.element.css({ overflowY: b ? "auto" : "hidden" });
BI.nextTick(()=> {
this.element.css({ overflowY: b ? "auto" : "hidden" });
});
}
},
}
getScrollLeft: function () {
getScrollLeft() {
return this.options.scrollLeft;
},
getScrollTop: function () {
}
getScrollTop() {
return this.options.scrollTop;
},
}
getMaxScrollLeft: function () {
getMaxScrollLeft() {
return this._getMaxScrollLeft();
},
}
getMaxScrollTop: function () {
getMaxScrollTop() {
return this._getMaxScrollTop();
},
}
setEstimatedColumnSize: function (width) {
setEstimatedColumnSize(width) {
this.options.estimatedColumnSize = width;
},
}
setEstimatedRowSize: function (height) {
setEstimatedRowSize(height) {
this.options.estimatedRowSize = height;
},
}
// 重新计算children
_reRange: function () {
_reRange() {
this.renderRange = {};
},
}
_clearChildren: function () {
_clearChildren() {
this.container._children = {};
this.container.attr("items", []);
},
}
restore: function () {
BI.each(this.renderedCells, function (i, cell) {
restore() {
BI.each(this.renderedCells, (i, cell)=> {
cell.el._destroy();
});
this._clearChildren();
@ -423,14 +426,12 @@ BI.GridView = BI.inherit(BI.Widget, {
this.renderedKeys = [];
this.renderRange = {};
this._scrollLock = false;
},
}
populate: function (items) {
populate(items) {
if (items && items !== this.options.items) {
this.restore();
}
this._populate(items);
},
});
BI.GridView.EVENT_SCROLL = "EVENT_SCROLL";
BI.shortcut("bi.grid_view", BI.GridView);
}
}

42
src/base/index.js

@ -1,15 +1,57 @@
import Pane from "./1.pane";
import Single from "./single/0.single";
import Text from "./single/1.text";
import A from "./single/a/a";
import Tip from "./single/tip/0.tip";
import Toast from "./single/tip/tip.toast";
import Tooltip from "./single/tip/tip.tooltip";
import Drawer from "./layer/layer.drawer";
import { Popover, BarPopover } from "./layer/layer.popover";
import PopupView from "./layer/layer.popup";
import SearcherView from "./layer/layer.searcher";
import ListView from "./list/listview";
import VirtualGroupList from "./list/virtualgrouplist";
import VirtualList from "./list/virtuallist";
import GridView from "./grid/grid";
import Pager from "./pager/pager";
BI.extend(BI, {
Pane,
Single,
Text,
A,
Tip,
Toast,
Tooltip,
Drawer,
Popover,
BarPopover,
PopupView,
SearcherView,
ListView,
VirtualGroupList,
VirtualList,
GridView,
Pager,
});
export {
Pane,
Single,
Text,
A,
Tip,
Toast,
Tooltip,
Drawer,
Popover,
BarPopover,
PopupView,
SearcherView,
ListView,
VirtualGroupList,
VirtualList,
GridView,
Pager,
}

6
src/base/layer/layer.drawer.js

@ -4,9 +4,9 @@
* @extends BI.Widget
*/
import { shortcut } from "../../core/decorator";
import { Widget, shortcut } from "../../core";
@shortcut()
export class Drawer extends BI.Widget {
export default class Drawer extends Widget {
SIZE = {
SMALL: "small",
NORMAL: "normal",
@ -234,4 +234,4 @@ export class Drawer extends BI.Widget {
}
}
BI.extend(BI, { Drawer });

9
src/base/layer/layer.popover.js

@ -4,9 +4,9 @@
* @extends BI.Widget
*/
import { shortcut } from "../../core/decorator";
import { Widget, shortcut } from "../../core";
@shortcut()
export class Popover extends BI.Widget {
export class Popover extends Widget {
_constant = {
SIZE: {
SMALL: "small",
@ -238,10 +238,8 @@ export class Popover extends BI.Widget {
}
}
BI.extend(BI, { Popover });
@shortcut()
export class BarPopover extends BI.Popover {
export class BarPopover extends Popover {
static xtype = "bi.bar_popover";
_defaultConfig() {
@ -278,5 +276,4 @@ export class BarPopover extends BI.Popover {
}
}
BI.extend(BI, { BarPopover });

14
src/base/layer/layer.popup.js

@ -4,9 +4,9 @@
* @extends BI.Widget
*/
import { shortcut } from "../../core/decorator";
import { Widget, shortcut } from "../../core";
@shortcut()
export class PopupView extends BI.Widget {
export default class PopupView extends Widget {
_const = {
TRIANGLE_LENGTH: 12,
}
@ -80,13 +80,10 @@ export class PopupView extends BI.Widget {
this.view = this._createView();
this.toolbar = this._createToolBar();
const self = this;
// TODO:这里需要调整转化方式,仍然采用原来的self
this.view.on(BI.Controller.EVENT_CHANGE, function (type) {
// 箭头函数没有自己的arguments,只会获取外层的,若要获取自己的,需通过剩余参数写法,但这样得到的仍然不是类数组
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);
this.view.on(BI.Controller.EVENT_CHANGE, (type, ...args)=> {
this.fireEvent.apply(this, [BI.Controller.EVENT_CHANGE, type, args]);
if (type === BI.Events.CLICK) {
self.fireEvent(PopupView.EVENT_CHANGE);
this.fireEvent(PopupView.EVENT_CHANGE);
}
});
@ -434,4 +431,3 @@ export class PopupView extends BI.Widget {
}
BI.extend(BI, { PopupView });

7
src/base/layer/layer.searcher.js

@ -6,9 +6,11 @@
* @extends BI.Pane
*/
import { shortcut } from "../../core/decorator";
import { shortcut } from "../../core";
import Pane from "../1.pane";
@shortcut()
export class SearcherView extends BI.Pane {
export default class SearcherView extends Pane {
static xtype = "bi.searcher_view";
static EVENT_CHANGE = "EVENT_CHANGE";
@ -142,4 +144,3 @@ export class SearcherView extends BI.Pane {
}
}
BI.extend(BI, { SearcherView });

250
src/base/list/listview.js

@ -5,141 +5,145 @@
* @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 = {};
},
import { Widget, shortcut } from "../../core";
@shortcut()
export default class ListView extends Widget {
props() {
return {
baseCls: "bi-list-view",
overscanHeight: 100,
blockSize: 10,
scrollTop: 0,
el: {},
items: [],
itemFormatter: (item, index)=> {
return item;
},
};
}
render: function () {
var self = this, o = this.options;
init() {
this.renderedIndex = -1;
this.cache = {};
}
return {
type: "bi.vertical",
items: [BI.extend({
type: "bi.vertical",
scrolly: false,
ref: function (_ref) {
self.container = _ref;
},
}, o.el)],
element: this,
};
},
static xtype = "bi.list_view";
// 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 () {
if (!self.element.is(":visible")) {
return;
}
var width = self.element.width(),
height = self.element.height();
if (width !== lastWidth || height !== lastHeight) {
lastWidth = width;
lastHeight = height;
self._calculateBlocksToRender();
}
});
},
render() {
const { el } = this.options;
_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;
return {
type: "bi.vertical",
items: [BI.extend({
type: "bi.vertical",
scrolly: false,
ref: (_ref)=> {
this.container = _ref;
},
}, el)],
element: this,
};
}
function getElementHeight() {
return self.container.element.height();
// mounted之后绑定事件
mounted() {
const o = this.options;
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
o.items = BI.isFunction(o.items) ? this.__watch(o.items, (context, newValue)=> {
this.populate(newValue);
}) : o.items;
this._populate();
this.element.scroll((e)=> {
o.scrollTop = this.element.scrollTop();
this._calculateBlocksToRender();
});
let lastWidth = this.element.width(),
lastHeight = this.element.height();
BI.ResizeDetector.addResizeListener(this, ()=> {
if (!this.element.is(":visible")) {
return;
}
const width = this.element.width(),
height = this.element.height();
if (width !== lastWidth || height !== lastHeight) {
lastWidth = width;
lastHeight = height;
this._calculateBlocksToRender();
}
});
}
_renderMoreIf() {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + blockSize)) || 0;
let cnt = this.renderedIndex + 1;
let lastHeight;
const getElementHeight = ()=> {
return this.container.element.height();
}
lastHeight = getElementHeight();
while ((lastHeight) < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize);
this.container.addItems(itemsArr.map((item, i)=> {
return itemFormatter(item, index + i);
}), this);
const addedHeight = getElementHeight() - lastHeight;
this.cache[cnt] = {
index: index,
scrollTop: lastHeight,
height: addedHeight,
};
this.renderedIndex = cnt;
cnt++;
index += blockSize;
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() {
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
}
this._renderMoreIf();
}
_calculateBlocksToRender: function () {
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
}
this._renderMoreIf();
},
_populate(items) {
const { scrollTop } = this.options;
if (items && this.options.items !== items) {
this.options.items = items;
}
this._calculateBlocksToRender();
this.element.scrollTop(scrollTop);
}
_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() {
this.renderedIndex = -1;
this.container.empty();
this.cache = {};
}
restore: function () {
this.renderedIndex = -1;
this.container.empty();
this.cache = {};
},
scrollTo(scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this.element.scrollTop(scrollTop);
}
scrollTo: function (scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this.element.scrollTop(scrollTop);
},
populate(items) {
if (items && this.options.items !== items) {
this.restore();
}
this._populate(items);
}
populate: function (items) {
if (items && this.options.items !== items) {
this.restore();
}
this._populate(items);
},
beforeDestroy() {
BI.ResizeDetector.removeResizeListener(this);
this.restore();
}
beforeDestroy: function () {
BI.ResizeDetector.removeResizeListener(this);
this.restore();
},
});
BI.shortcut("bi.list_view", BI.ListView);
}

353
src/base/list/virtualgrouplist.js

@ -5,194 +5,197 @@
* @class BI.VirtualList
* @extends BI.Widget
*/
BI.VirtualGroupList = BI.inherit(BI.Widget, {
props: function () {
return {
baseCls: "bi-virtual-group-list",
overscanHeight: 100,
blockSize: 10,
scrollTop: 0,
rowHeight: "auto",
items: [],
el: {},
itemFormatter: function (item, index) {
return item;
},
};
},
init: function () {
this.renderedIndex = -1;
},
import { Widget, shortcut } from "../../core";
@shortcut()
export default class VirtualGroupList extends Widget {
props() {
return {
baseCls: "bi-virtual-group-list",
overscanHeight: 100,
blockSize: 10,
scrollTop: 0,
rowHeight: "auto",
items: [],
el: {},
itemFormatter: (item, index)=> {
return item;
},
};
}
render: function () {
var self = this, o = this.options;
init() {
this.renderedIndex = -1;
}
return {
type: "bi.vertical",
items: [{
type: "bi.layout",
ref: function () {
self.topBlank = this;
},
}, {
type: "bi.virtual_group",
height: o.rowHeight * o.items.length,
ref: function () {
self.container = this;
},
layouts: [BI.extend({
type: "bi.vertical",
scrolly: false,
}, o.el)],
}, {
type: "bi.layout",
ref: function () {
self.bottomBlank = this;
},
}],
element: this,
};
},
static xtype = "bi.virtual_group_list";
// 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.ticking = false;
this.element.scroll(function () {
o.scrollTop = self.element.scrollTop();
if (!self.ticking) {
requestAnimationFrame(function () {
self._calculateBlocksToRender();
self.ticking = false;
});
self.ticking = true;
}
});
BI.ResizeDetector.addResizeListener(this, function () {
if (self.element.is(":visible")) {
self._calculateBlocksToRender();
}
});
},
render() {
const { rowHeight, items, el } = this.options;
_isAutoHeight: function () {
return !BI.isNumber(this.options.rowHeight);
},
_renderMoreIf: function () {
var self = this, o = this.options;
var height = this.element.height();
var minContentHeight = o.scrollTop + height + o.overscanHeight;
var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1;
var lastHeight;
function getElementHeight () {
return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height();
return {
type: "bi.vertical",
items: [{
type: "bi.layout",
ref: ()=> {
this.topBlank = this;
},
}, {
type: "bi.virtual_group",
height: rowHeight * items.length,
ref: ()=> {
this.container = this;
},
layouts: [BI.extend({
type: "bi.vertical",
scrolly: false,
}, el)],
}, {
type: "bi.layout",
ref: ()=> {
this.bottomBlank = this;
},
}],
element: this,
};
}
// mounted之后绑定事件
mounted() {
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
const o = this.options;
o.items = BI.isFunction(o.items) ? this.__watch(o.items, (context, newValue)=> {
this.populate(newValue);
}) : o.items;
this._populate();
this.ticking = false;
this.element.scroll(()=> {
o.scrollTop = this.element.scrollTop();
if (!this.ticking) {
requestAnimationFrame(function () {
this._calculateBlocksToRender();
this.ticking = false;
});
this.ticking = true;
}
lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight();
while (lastHeight < minContentHeight && index < o.items.length) {
var items = o.items.slice(index, index + o.blockSize);
this.container[self.renderedIndex === -1 ? "populate" : "addItems"](items.map(function (item, i) {
return o.itemFormatter(item, index + i);
}), this);
var elementHeight = getElementHeight();
var addedHeight = elementHeight - lastHeight;
this.tree.set(cnt, addedHeight);
this.renderedIndex = cnt;
cnt++;
index += o.blockSize;
lastHeight = this.renderedIndex === -1 ? 0 : elementHeight;
});
BI.ResizeDetector.addResizeListener(this, ()=> {
if (this.element.is(":visible")) {
this._calculateBlocksToRender();
}
},
});
}
_calculateBlocksToRender: function () {
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
}
var o = this.options;
this._isAutoHeight() && 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 items = [];
var topHeight = this.tree.sumTo(Math.max(-1, start - 1));
this.topBlank.setHeight(topHeight + "px");
if (this._isAutoHeight()) {
for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
var index = i * o.blockSize;
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
items.push(o.items[j]);
}
}
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px");
this.container.populate(items.map(function (item, i) {
return o.itemFormatter(item, (start < 0 ? 0 : start) * o.blockSize + i);
}));
} else {
for (var i = (start < 0 ? 0 : start); i <= end; i++) {
var index = i * o.blockSize;
for (var j = index; j < index + o.blockSize && j < o.items.length; j++) {
items.push(o.items[j]);
}
}
this.container.element.height(o.rowHeight * o.items.length - topHeight);
this.container.populate(items.map(function (item, i) {
return o.itemFormatter(item, (start < 0 ? 0 : start) * o.blockSize + i);
}));
}
},
_populate: function (items) {
var o = this.options;
if (items && this.options.items !== items) {
// 重新populate一组items,需要重新对线段树分块
this.options.items = items;
this._restore();
}
this.tree = BI.PrefixIntervalTree.uniform(Math.ceil(o.items.length / o.blockSize), this._isAutoHeight() ? 0 : o.rowHeight * o.blockSize);
_isAutoHeight() {
return !BI.isNumber(this.options.rowHeight);
}
this._calculateBlocksToRender();
try {
this.element.scrollTop(o.scrollTop);
} catch (e) {
}
},
_renderMoreIf() {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.renderedIndex + 1) * blockSize, cnt = this.renderedIndex + 1;
let lastHeight;
const getElementHeight = ()=> {
return this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height();
}
lastHeight = this.renderedIndex === -1 ? 0 : getElementHeight();
while (lastHeight < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize);
this.container[this.renderedIndex === -1 ? "populate" : "addItems"](itemsArr.map((item, i)=> {
return itemFormatter(item, index + i);
}), this);
const elementHeight = getElementHeight();
const addedHeight = elementHeight - lastHeight;
this.tree.set(cnt, addedHeight);
this.renderedIndex = cnt;
cnt++;
index += blockSize;
lastHeight = this.renderedIndex === -1 ? 0 : elementHeight;
}
}
_restore: function () {
this.renderedIndex = -1;
// 依赖于cache的占位元素也要初始化
this.topBlank.setHeight(0);
this.bottomBlank.setHeight(0);
},
_calculateBlocksToRender() {
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
}
const { scrollTop, overscanHeight, blockSize, items, itemFormatter, rowHeight } = this.options;
this._isAutoHeight() && this._renderMoreIf();
const height = this.element.height();
const minContentHeightFrom = scrollTop - overscanHeight;
const minContentHeightTo = scrollTop + height + overscanHeight;
const start = this.tree.greatestLowerBound(minContentHeightFrom);
const end = this.tree.leastUpperBound(minContentHeightTo);
const itemsArr = [];
const topHeight = this.tree.sumTo(Math.max(-1, start - 1));
this.topBlank.setHeight(topHeight + "px");
if (this._isAutoHeight()) {
for (let i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
const index = i * blockSize;
for (let j = index; j < index + blockSize && j < items.length; j++) {
itemsArr.push(items[j]);
}
}
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px");
this.container.populate(itemsArr.map((item, i)=> {
return itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i);
}));
} else {
for (let i = (start < 0 ? 0 : start); i <= end; i++) {
const index = i * blockSize;
for (let j = index; j < index + blockSize && j < items.length; j++) {
itemsArr.push(items[j]);
}
}
this.container.element.height(rowHeight * items.length - topHeight);
this.container.populate(itemsArr.map((item, i)=> {
return itemFormatter(item, (start < 0 ? 0 : start) * blockSize + i);
}));
}
}
_populate(items) {
const { blockSize, rowHeight, scrollTop } = this.options;
if (items && this.options.items !== items) {
// 重新populate一组items,需要重新对线段树分块
this.options.items = items;
this._restore();
}
this.tree = BI.PrefixIntervalTree.uniform(Math.ceil(this.options.items.length / blockSize), this._isAutoHeight() ? 0 : rowHeight * blockSize);
// 暂时只支持固定行高的场景
scrollTo: function (scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this._calculateBlocksToRender();
try {
this.element.scrollTop(scrollTop);
},
} catch (e) {
}
}
restore: function () {
this.options.scrollTop = 0;
this._restore();
},
_restore() {
this.renderedIndex = -1;
// 依赖于cache的占位元素也要初始化
this.topBlank.setHeight(0);
this.bottomBlank.setHeight(0);
}
populate: function (items) {
this._populate(items);
},
// 暂时只支持固定行高的场景
scrollTo(scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this.element.scrollTop(scrollTop);
}
beforeDestroy: function () {
BI.ResizeDetector.removeResizeListener(this);
this.restore();
}
});
BI.shortcut("bi.virtual_group_list", BI.VirtualGroupList);
restore() {
this.options.scrollTop = 0;
this._restore();
}
populate(items) {
this._populate(items);
}
beforeDestroy() {
BI.ResizeDetector.removeResizeListener(this);
this.restore();
}
}

357
src/base/list/virtuallist.js

@ -5,213 +5,214 @@
* @class BI.VirtualList
* @extends BI.Widget
*/
BI.VirtualList = BI.inherit(BI.Widget, {
props: function () {
import { Widget, shortcut } from "../../core";
@shortcut()
export default class VirtualList extends Widget {
props() {
return {
baseCls: "bi-virtual-list",
overscanHeight: 100,
blockSize: 10,
scrollTop: 0,
items: [],
itemFormatter: function (item, index) {
itemFormatter: (item, index)=> {
return item;
},
};
},
}
init: function () {
init() {
this.renderedIndex = -1;
this.cache = {};
},
render: function () {
var self = this;
}
return {
type: "bi.vertical",
items: [{
type: "bi.layout",
ref: function () {
self.topBlank = this;
},
}, {
type: "bi.vertical",
scrolly: false,
ref: function () {
self.container = this;
},
}, {
type: "bi.layout",
ref: function () {
self.bottomBlank = this;
},
}],
};
},
static xtype = "bi.virtual_list";
render() {
return {
type: "bi.vertical",
items: [{
type: "bi.layout",
ref: (_ref)=> {
this.topBlank = _ref;
},
}, {
type: "bi.vertical",
scrolly: false,
ref: (_ref)=> {
this.container = _ref;
},
}, {
type: "bi.layout",
ref: (_ref)=> {
this.bottomBlank = _ref;
},
}],
};
}
// 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();
});
BI.ResizeDetector.addResizeListener(this, function () {
if (self.element.is(":visible")) {
self._calculateBlocksToRender();
}
});
},
mounted() {
// 这里无法进行结构,因为存在赋值操作,如果使用结构则this.options的值不会跟随变化
const o = this.options;
o.items = BI.isFunction(o.items) ? this.__watch(o.items, (context, newValue)=> {
this.populate(newValue);
}) : o.items;
this._populate();
this.element.scroll((e)=> {
o.scrollTop = this.element.scrollTop();
this._calculateBlocksToRender();
});
BI.ResizeDetector.addResizeListener(this, ()=> {
if (this.element.is(":visible")) {
this._calculateBlocksToRender();
}
});
}
_renderMoreIf: function () {
var self = this, o = this.options;
var height = this.element.height();
var minContentHeight = o.scrollTop + height + o.overscanHeight;
var index = (this.renderedIndex + 1) * o.blockSize, cnt = this.renderedIndex + 1;
var lastHeight;
function getElementHeight() {
return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.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.tree.set(cnt, addedHeight);
this.renderedIndex = cnt;
cnt++;
index += o.blockSize;
lastHeight = getElementHeight();
}
},
_renderMoreIf() {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
const height = this.element.height();
const minContentHeight = scrollTop + height + overscanHeight;
let index = (this.renderedIndex + 1) * blockSize, cnt = this.renderedIndex + 1;
let lastHeight;
const getElementHeight = ()=> {
return this.container.element.height() + this.topBlank.element.height() + this.bottomBlank.element.height();
}
lastHeight = getElementHeight();
while (lastHeight < minContentHeight && index < items.length) {
const itemsArr = items.slice(index, index + blockSize);
this.container.addItems(itemsArr.map((item, i)=> {
return itemFormatter(item, index + i);
}), this);
const addedHeight = getElementHeight() - lastHeight;
this.tree.set(cnt, addedHeight);
this.renderedIndex = cnt;
cnt++;
index += blockSize;
lastHeight = getElementHeight();
}
}
_calculateBlocksToRender: function () {
var o = this.options;
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
_calculateBlocksToRender() {
const { scrollTop, overscanHeight, blockSize, items, itemFormatter } = this.options;
// BI-115750 不可见状态下依赖元素实际尺寸构造的线段树会分段错误,所以不进行后续计算和线段树的初始化。
// 这样从不可见状态变为可见状态能够重新触发线段树初始化
if (!this.element.is(":visible")) {
return;
}
this._renderMoreIf();
const height = this.element.height();
const minContentHeightFrom = scrollTop - overscanHeight;
const minContentHeightTo = scrollTop + height + overscanHeight;
const start = this.tree.greatestLowerBound(minContentHeightFrom);
const end = this.tree.leastUpperBound(minContentHeightTo);
const needDestroyed = [], needMount = [];
for (let i = 0; i < start; i++) {
let index = i * blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
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 needDestroyed = [], needMount = [];
for (var i = 0; i < start; i++) {
var index = i * o.blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
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;
if (!this.cache[i].destroyed) {
for (let j = index; j < index + blockSize && j < items.length; j++) {
needDestroyed.push(this.container._children[j]);
this.container._children[j] = null;
}
this.cache[i].destroyed = true;
}
for (var i = end + 1; i <= this.renderedIndex; i++) {
var index = i * o.blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
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;
}
}
for (let i = end + 1; i <= this.renderedIndex; i++) {
let index = i * blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
if (!this.cache[i].destroyed) {
for (let j = index; j < index + blockSize && j < items.length; j++) {
needDestroyed.push(this.container._children[j]);
this.container._children[j] = null;
}
var firstFragment = BI.Widget._renderEngine.createFragment(),
lastFragment = BI.Widget._renderEngine.createFragment();
var currentFragment = firstFragment;
for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
var index = i * o.blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
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._addElement(j, o.itemFormatter(o.items[j], j), this);
needMount.push(w);
currentFragment.appendChild(w.element[0]);
}
this.cache[i].destroyed = false;
}
this.cache[i].destroyed = true;
}
}
const firstFragment = BI.Widget._renderEngine.createFragment(),
lastFragment = BI.Widget._renderEngine.createFragment();
let currentFragment = firstFragment;
for (let i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) {
const index = i * blockSize;
if (!this.cache[i]) {
this.cache[i] = {};
}
this.container.element.prepend(firstFragment);
this.container.element.append(lastFragment);
this.topBlank.setHeight(this.tree.sumTo(Math.max(-1, start - 1)) + "px");
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px");
BI.each(needMount, function (i, child) {
child && child._mount();
});
BI.each(needDestroyed, function (i, child) {
child && child._destroy();
});
},
_populate: function (items) {
var o = this.options;
if (items && this.options.items !== items) {
this.options.items = items;
if (!this.cache[i].destroyed) {
currentFragment = lastFragment;
}
this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize));
this._calculateBlocksToRender();
try {
this.element.scrollTop(o.scrollTop);
} catch (e) {
if (this.cache[i].destroyed === true) {
for (let j = index; j < index + blockSize && j < items.length; j++) {
const w = this.container._addElement(j, itemFormatter(items[j], j), this);
needMount.push(w);
currentFragment.appendChild(w.element[0]);
}
this.cache[i].destroyed = false;
}
},
_clearChildren: function () {
BI.each(this.container._children, function (i, cell) {
cell && cell._destroy();
});
this.container._children = {};
this.container.attr("items", []);
},
}
this.container.element.prepend(firstFragment);
this.container.element.append(lastFragment);
this.topBlank.setHeight(this.tree.sumTo(Math.max(-1, start - 1)) + "px");
this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - this.tree.sumTo(Math.min(end, this.renderedIndex)) + "px");
BI.each(needMount, (i, child)=> {
child && child._mount();
});
BI.each(needDestroyed, (i, child)=> {
child && child._destroy();
});
}
_populate(items) {
const { blockSize, scrollTop } = this.options;
if (items && this.options.items !== items) {
this.options.items = items;
}
this.tree = BI.PrefixIntervalTree.empty(Math.ceil(this.options.items.length / blockSize));
scrollTo: function (scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this._calculateBlocksToRender();
try {
this.element.scrollTop(scrollTop);
},
} catch (e) {
}
}
restore: function () {
this.renderedIndex = -1;
this._clearChildren();
this.cache = {};
this.options.scrollTop = 0;
// 依赖于cache的占位元素也要初始化
this.topBlank.setHeight(0);
this.bottomBlank.setHeight(0);
},
_clearChildren() {
BI.each(this.container._children, (i, cell)=> {
cell && cell._destroy();
});
this.container._children = {};
this.container.attr("items", []);
}
populate: function (items) {
if (items && this.options.items !== items) {
this.restore();
}
this._populate(items);
},
scrollTo(scrollTop) {
this.options.scrollTop = scrollTop;
this._calculateBlocksToRender();
this.element.scrollTop(scrollTop);
}
restore() {
this.renderedIndex = -1;
this._clearChildren();
this.cache = {};
this.options.scrollTop = 0;
// 依赖于cache的占位元素也要初始化
this.topBlank.setHeight(0);
this.bottomBlank.setHeight(0);
}
beforeDestroy: function () {
BI.ResizeDetector.removeResizeListener(this);
populate(items) {
if (items && this.options.items !== items) {
this.restore();
}
});
BI.shortcut("bi.virtual_list", BI.VirtualList);
this._populate(items);
}
beforeDestroy() {
BI.ResizeDetector.removeResizeListener(this);
this.restore();
}
}

151
src/base/pager/pager.js

@ -5,9 +5,11 @@
* @class BI.Pager
* @extends BI.Widget
*/
BI.Pager = BI.inherit(BI.Widget, {
_defaultConfig: function () {
return BI.extend(BI.Pager.superclass._defaultConfig.apply(this, arguments), {
import { Widget, shortcut } from "../../core";
@shortcut()
export default class Pager extends Widget {
_defaultConfig() {
return BI.extend(super._defaultConfig(arguments), {
baseCls: "bi-pager",
behaviors: {},
layouts: [{
@ -32,15 +34,18 @@ BI.Pager = BI.inherit(BI.Widget, {
next: "下一页",
firstPage: 1,
lastPage: function () { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法
lastPage: ()=> { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法
return 1;
},
hasPrev: BI.emptyFn, // pages不可用时有效
hasNext: BI.emptyFn, // pages不可用时有效
});
},
}
render: function () {
static xtype = "bi.pager";
static EVENT_CHANGE = "EVENT_CHANGE";
static EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE";
render() {
this.currPage = BI.result(this.options, "curr");
// 翻页太灵敏
// this._lock = false;
@ -48,18 +53,19 @@ BI.Pager = BI.inherit(BI.Widget, {
// self._lock = false;
// }, 300);
this._populate();
},
}
_populate: function () {
var self = this, o = this.options, view = [], dict = {};
_populate() {
const o = this.options, view = [], dict = {};
const { dynamicShow, dynamicShowPrevNext, hasPrev, dynamicShowFirstLast, hasNext, behaviors, layouts, jump } = this.options;
this.empty();
var pages = BI.result(o, "pages");
var curr = BI.result(this, "currPage");
var groups = BI.result(o, "groups");
var first = BI.result(o, "first");
var last = BI.result(o, "last");
var prev = BI.result(o, "prev");
var next = BI.result(o, "next");
const pages = BI.result(o, "pages");
const curr = BI.result(this, "currPage");
let groups = BI.result(o, "groups");
let first = BI.result(o, "first");
let last = BI.result(o, "last");
const prev = BI.result(o, "prev");
const next = BI.result(o, "next");
if (pages === false) {
groups = 0;
@ -73,24 +79,24 @@ BI.Pager = BI.inherit(BI.Widget, {
dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups));
// 当前页非首页,则输出上一页
if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) {
if (((!dynamicShow && !dynamicShowPrevNext) || curr > 1) && prev !== false) {
if (BI.isKey(prev)) {
view.push({
text: prev,
value: "prev",
disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false),
disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false),
});
} else {
view.push({
el: BI.extend({
disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false),
disabled: pages === false ? hasPrev(curr) === false : !(curr > 1 && prev !== false),
}, prev),
});
}
}
// 当前组非首组,则输出首页
if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) {
if (((!dynamicShow && !dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) {
view.push({
text: first,
value: "first",
@ -109,14 +115,14 @@ BI.Pager = BI.inherit(BI.Widget, {
dict.poor = Math.floor((groups - 1) / 2);
dict.start = dict.index > 1 ? curr - dict.poor : 1;
dict.end = dict.index > 1 ? (function () {
var max = curr + (groups - dict.poor - 1);
const max = curr + (groups - dict.poor - 1);
return max > pages ? pages : max;
}()) : groups;
if (dict.end - dict.start < groups - 1) { // 最后一组状态
dict.start = dict.end - groups + 1;
}
var s = dict.start, e = dict.end;
let s = dict.start, e = dict.end;
if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) {
s++;
e--;
@ -137,7 +143,7 @@ BI.Pager = BI.inherit(BI.Widget, {
}
// 总页数大于连续分页数,且当前组最大页小于总页,输出尾页
if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) {
if (((!dynamicShow && !dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) {
if (pages > groups && dict.end < pages && groups !== 0 && groups !== pages - 1) {
view.push({
type: "bi.label",
@ -154,11 +160,11 @@ BI.Pager = BI.inherit(BI.Widget, {
// 当前页不为尾页时,输出下一页
dict.flow = !prev && groups === 0;
if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) {
if (((!dynamicShow && !dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) {
view.push((function () {
if (BI.isKey(next)) {
if (pages === false) {
return { text: next, value: "next", disabled: o.hasNext(curr) === false };
return { text: next, value: "next", disabled: hasNext(curr) === false };
}
return (dict.flow && curr === pages)
@ -170,7 +176,7 @@ BI.Pager = BI.inherit(BI.Widget, {
return {
el: BI.extend({
disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow),
disabled: pages === false ? hasNext(curr) === false : !(curr !== pages && next || dict.flow),
}, next),
};
}()));
@ -179,7 +185,7 @@ BI.Pager = BI.inherit(BI.Widget, {
this.button_group = BI.createWidget({
type: "bi.button_group",
element: this,
items: BI.map(view, function (idx, v) {
items: BI.map(view, (idx, v)=> {
v = BI.extend({
cls: "bi-list-item-select bi-border-radius",
height: 23,
@ -189,87 +195,85 @@ BI.Pager = BI.inherit(BI.Widget, {
return BI.formatEL(v);
}),
behaviors: o.behaviors,
layouts: o.layouts,
behaviors,
layouts,
});
this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) {
this.button_group.on(BI.Controller.EVENT_CHANGE, (type, value, obj, ...args)=> {
// if (self._lock === true) {
// return;
// }
// self._lock = true;
// self._debouce();
if (type === BI.Events.CLICK) {
var v = self.button_group.getValue()[0];
var v = this.button_group.getValue()[0];
switch (v) {
case "first":
self.currPage = 1;
this.currPage = 1;
break;
case "last":
self.currPage = pages;
this.currPage = pages;
break;
case "prev":
self.currPage--;
this.currPage--;
break;
case "next":
self.currPage++;
this.currPage++;
break;
default:
self.currPage = v;
this.currPage = v;
break;
}
o.jump.apply(self, [{
jump.apply(this, [{
pages: pages,
curr: self.currPage,
curr: this.currPage,
}]);
self._populate();
self.fireEvent(BI.Pager.EVENT_CHANGE, obj);
this._populate();
this.fireEvent(Pager.EVENT_CHANGE, obj);
}
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);
this.fireEvent.apply(this, [BI.Controller.EVENT_CHANGE, type, value, obj, args]);
});
this.fireEvent(BI.Pager.EVENT_AFTER_POPULATE);
},
this.fireEvent(Pager.EVENT_AFTER_POPULATE);
}
getCurrentPage: function () {
getCurrentPage() {
return this.currPage;
},
}
setAllPages: function (pages) {
setAllPages(pages) {
this.options.pages = pages;
this._populate();
},
}
hasPrev: function (v) {
hasPrev(v) {
v || (v = 1);
var o = this.options;
var pages = this.options.pages;
const { pages, hasPrev } = this.options;
return pages === false ? o.hasPrev(v) : v > 1;
},
return pages === false ? hasPrev(v) : v > 1;
}
hasNext: function (v) {
hasNext(v) {
v || (v = 1);
var o = this.options;
var pages = this.options.pages;
const { pages, hasNext } = this.options;
return pages === false ? hasNext(v) : v < pages;
}
return pages === false ? o.hasNext(v) : v < pages;
},
setValue: function (v) {
var o = this.options;
setValue(v) {
const o = this.options;
const { pages } = this.options;
v = v || 0;
v = v < 1 ? 1 : v;
if (o.pages === false) {
if (pages === false) {
var lastPage = BI.result(o, "lastPage"), firstPage = 1;
this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v));
} else {
v = v > o.pages ? o.pages : v;
v = v > pages ? pages : v;
this.currPage = v;
}
this._populate();
},
}
getValue: function () {
var val = this.button_group.getValue()[0];
getValue() {
const val = this.button_group.getValue()[0];
switch (val) {
case "prev":
return -1;
@ -282,19 +286,16 @@ BI.Pager = BI.inherit(BI.Widget, {
default:
return val;
}
},
}
attr: function (key, value) {
BI.Pager.superclass.attr.apply(this, arguments);
attr(key, value) {
super.attr(arguments);
if (key === "curr") {
this.currPage = BI.result(this.options, "curr");
}
},
}
populate: function () {
populate() {
this._populate();
},
});
BI.Pager.EVENT_CHANGE = "EVENT_CHANGE";
BI.Pager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE";
BI.shortcut("bi.pager", BI.Pager);
}
}

7
src/base/single/a/a.js

@ -6,9 +6,10 @@
* @extends BI.Text
* @abstract
*/
import { shortcut } from "../../../core/decorator";
import { shortcut } from "../../../core";
import Text from "../1.text";
@shortcut()
export class A extends BI.Text {
export default class A extends Text {
static xtype = "bi.a";
_defaultConfig() {
@ -34,5 +35,3 @@ export class A extends BI.Text {
}
}
BI.extend(BI, { A });

5
src/base/single/tip/0.tip.js

@ -6,7 +6,9 @@
* @extends BI.Single
* @abstract
*/
export class Tip extends BI.Single {
import Single from "../0.single";
export default class Tip extends Single {
_defaultConfig() {
const conf = super._defaultConfig(arguments);
return BI.extend(conf, {
@ -21,4 +23,3 @@ export class Tip extends BI.Single {
}
}
BI.extend(BI, { Tip });

6
src/base/single/tip/tip.toast.js

@ -6,9 +6,10 @@
* @extends BI.Tip
*/
import { shortcut } from "../../../core/decorator";
import { shortcut } from "../../../core";
import Tip from "./0.tip";
@shortcut()
export class Toast extends BI.Tip {
export default class Toast extends Tip {
_const= {
closableMinWidth: 146,
minWidth: 100,
@ -124,4 +125,3 @@ export class Toast extends BI.Tip {
}
BI.extend(BI, { Toast });

7
src/base/single/tip/tip.tooltip.js

@ -6,9 +6,10 @@
* @extends BI.Tip
*/
import { shortcut } from "../../../core/decorator";
import { shortcut } from "../../../core";
import Tip from "./0.tip";
@shortcut()
export class Tooltip extends BI.Tip {
export default class Tooltip extends Tip {
_const = {
hgap: 8,
vgap: 4,
@ -90,5 +91,3 @@ export class Tooltip extends BI.Tip {
}
}
BI.extend(BI, { Tooltip });

Loading…
Cancel
Save