UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

373 lines (372 loc) • 15.8 kB
/** * DevExtreme (cjs/ui/grid_core/ui.grid.core.virtual_data_loader.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; exports.VirtualDataLoader = void 0; var _deferred = require("../../core/utils/deferred"); var _type = require("../../core/utils/type"); var NEW_SCROLLING_MODE = "scrolling.newMode"; var needTwoPagesLoading = function(that) { return that.option("scrolling.loadTwoPagesOnStart") || that._controller.isVirtual() || that._controller.getViewportItemIndex() > 0 }; var getBeginPageIndex = function(that) { return that._cache.length ? that._cache[0].pageIndex : -1 }; var getEndPageIndex = function(that) { return that._cache.length ? that._cache[that._cache.length - 1].pageIndex : -1 }; var fireChanged = function(that, changed, args) { that._isChangedFiring = true; changed(args); that._isChangedFiring = false }; var processDelayChanged = function(that, changed, args) { if (that._isDelayChanged) { that._isDelayChanged = false; fireChanged(that, changed, args); return true } }; var getViewportPageCount = function(that) { var pageSize = that._dataOptions.pageSize(); var preventPreload = that.option("scrolling.preventPreload"); if (preventPreload) { return 0 } var realViewportSize = that._controller.viewportSize(); if (that._controller.isVirtualMode() && that.option("scrolling.removeInvisiblePages")) { realViewportSize = 0; var viewportSize = that._controller.viewportSize() * that._controller.viewportItemSize(); var offset = that._controller.getContentOffset(); var position = that._controller.getViewportPosition(); var virtualItemsCount = that._controller.virtualItemsCount(); var totalItemsCount = that._dataOptions.totalItemsCount(); for (var itemIndex = virtualItemsCount.begin; itemIndex < totalItemsCount; itemIndex++) { if (offset >= position + viewportSize) { break } var itemSize = that._controller.getItemSizes()[itemIndex] || that._controller.viewportItemSize(); offset += itemSize; if (offset >= position) { realViewportSize++ } } } return pageSize && realViewportSize > 0 ? Math.ceil(realViewportSize / pageSize) : 1 }; var getPreloadPageCount = function(that, previous) { var preloadEnabled = that.option("scrolling.preloadEnabled"); var pageCount = getViewportPageCount(that); var isAppendMode = that._controller.isAppendMode(); if (pageCount) { if (previous) { pageCount = preloadEnabled ? 1 : 0 } else { if (preloadEnabled) { pageCount++ } if (isAppendMode || !needTwoPagesLoading(that)) { pageCount-- } } } return pageCount }; var getPageIndexForLoad = function(that) { var result = -1; var beginPageIndex = getBeginPageIndex(that); var dataOptions = that._dataOptions; if (beginPageIndex < 0) { result = that._pageIndex } else if (!that._cache[that._pageIndex - beginPageIndex]) { result = that._pageIndex } else if (beginPageIndex >= 0 && that._controller.viewportSize() >= 0) { if (beginPageIndex > 0) { var needToLoadPageBeforeLast = getEndPageIndex(that) + 1 === dataOptions.pageCount() && that._cache.length < getPreloadPageCount(that) + 1; var needToLoadPrevPage = needToLoadPageBeforeLast || that._pageIndex === beginPageIndex && getPreloadPageCount(that, true); if (needToLoadPrevPage) { result = beginPageIndex - 1 } } if (result < 0) { var needToLoadNextPage = beginPageIndex + that._cache.length <= that._pageIndex + getPreloadPageCount(that); if (needToLoadNextPage) { result = beginPageIndex + that._cache.length } } } if (that._loadingPageIndexes[result]) { result = -1 } return result }; var loadCore = function(that, pageIndex) { var dataOptions = that._dataOptions; if (pageIndex === that.pageIndex() || !dataOptions.isLoading() && pageIndex < dataOptions.pageCount() || !dataOptions.hasKnownLastPage() && pageIndex === dataOptions.pageCount()) { dataOptions.pageIndex(pageIndex); that._loadingPageIndexes[pageIndex] = true; return (0, _deferred.when)(dataOptions.load()).always((function() { that._loadingPageIndexes[pageIndex] = false })) } }; var processChanged = function(that, changed, changeType, isDelayChanged, removeCacheItem) { var dataOptions = that._dataOptions; var items = dataOptions.items().slice(); var change = (0, _type.isObject)(changeType) ? changeType : void 0; var isPrepend = "prepend" === changeType; var viewportItems = dataOptions.viewportItems(); if (changeType && (0, _type.isString)(changeType) && !that._isDelayChanged) { change = { changeType: changeType, items: items }; if (removeCacheItem) { change.removeCount = removeCacheItem.itemsCount; if (change.removeCount && dataOptions.correctCount) { change.removeCount = dataOptions.correctCount(viewportItems, change.removeCount, isPrepend) } } } var removeItemCount = removeCacheItem ? removeCacheItem.itemsLength : 0; if (removeItemCount && dataOptions.correctCount) { removeItemCount = dataOptions.correctCount(viewportItems, removeItemCount, isPrepend) } if ("append" === changeType) { viewportItems.push.apply(viewportItems, items); if (removeCacheItem) { viewportItems.splice(0, removeItemCount) } } else if (isPrepend) { viewportItems.unshift.apply(viewportItems, items); if (removeCacheItem) { viewportItems.splice(-removeItemCount) } } else { that._dataOptions.viewportItems(items) } dataOptions.updateLoading(); that._lastPageIndex = that.pageIndex(); that._isDelayChanged = isDelayChanged; if (!isDelayChanged) { fireChanged(that, changed, change) } }; var VirtualDataLoader = function() { function VirtualDataLoader(controller, dataOptions) { this._controller = controller; this._dataOptions = dataOptions; this._pageIndex = this._lastPageIndex = dataOptions.pageIndex(); this._cache = []; this._loadingPageIndexes = {} } var _proto = VirtualDataLoader.prototype; _proto.option = function() { return this._controller.option.apply(this._controller, arguments) }; _proto.viewportItemIndexChanged = function(itemIndex) { var pageSize = this._dataOptions.pageSize(); var pageCount = this._dataOptions.pageCount(); var virtualMode = this._controller.isVirtualMode(); var appendMode = this._controller.isAppendMode(); var totalItemsCount = this._dataOptions.totalItemsCount(); var newPageIndex; if (pageSize && (virtualMode || appendMode) && totalItemsCount >= 0) { var viewportSize = this._controller.viewportSize(); if (viewportSize && itemIndex + viewportSize >= totalItemsCount && !this._controller.isVirtual()) { if (this._dataOptions.hasKnownLastPage()) { newPageIndex = pageCount - 1; var lastPageSize = totalItemsCount % pageSize; if (newPageIndex > 0 && lastPageSize > 0 && lastPageSize < viewportSize) { newPageIndex-- } } else { newPageIndex = pageCount } } else { newPageIndex = Math.floor(itemIndex / pageSize); var maxPageIndex = pageCount - 1; newPageIndex = Math.max(newPageIndex, 0); newPageIndex = Math.min(newPageIndex, maxPageIndex) } this.pageIndex(newPageIndex); return this.load() } }; _proto.pageIndex = function(_pageIndex) { var isVirtualMode = this._controller.isVirtualMode(); var isAppendMode = this._controller.isAppendMode(); if (!this.option(NEW_SCROLLING_MODE) && (isVirtualMode || isAppendMode)) { if (void 0 !== _pageIndex) { this._pageIndex = _pageIndex } return this._pageIndex } else { return this._dataOptions.pageIndex(_pageIndex) } }; _proto.beginPageIndex = function(defaultPageIndex) { var beginPageIndex = getBeginPageIndex(this); if (beginPageIndex < 0) { beginPageIndex = void 0 !== defaultPageIndex ? defaultPageIndex : this.pageIndex() } return beginPageIndex }; _proto.endPageIndex = function() { var endPageIndex = getEndPageIndex(this); return endPageIndex > 0 ? endPageIndex : this._lastPageIndex }; _proto.pageSize = function() { return this._dataOptions.pageSize() }; _proto.load = function() { var _this = this; var dataOptions = this._dataOptions; var result; var isVirtualMode = this._controller.isVirtualMode(); var isAppendMode = this._controller.isAppendMode(); if (!this.option(NEW_SCROLLING_MODE) && (isVirtualMode || isAppendMode)) { var pageIndexForLoad = getPageIndexForLoad(this); if (pageIndexForLoad >= 0) { var loadResult = loadCore(this, pageIndexForLoad); if (loadResult) { result = new _deferred.Deferred; loadResult.done((function() { var delayDeferred = _this._delayDeferred; if (delayDeferred) { delayDeferred.done(result.resolve).fail(result.reject) } else { result.resolve() } })).fail(result.reject); dataOptions.updateLoading() } } } else { result = dataOptions.load() } if (!result && this._lastPageIndex !== this.pageIndex()) { this._dataOptions.onChanged({ changeType: "pageIndex" }) } return result || (new _deferred.Deferred).resolve() }; _proto.loadIfNeed = function() { var isVirtualMode = this._controller.isVirtualMode(); var isAppendMode = this._controller.isAppendMode(); if ((isVirtualMode || isAppendMode) && !this._dataOptions.isLoading() && (!this._isChangedFiring || this._controller.isVirtual())) { var position = this._controller.getViewportPosition(); if (position > 0) { this._controller._setViewportPositionCore(position) } else { this.load() } } }; _proto.handleDataChanged = function(callBase, e) { var _this2 = this; var dataOptions = this._dataOptions; var lastCacheLength = this._cache.length; var changeType; var removeInvisiblePages; var isVirtualMode = this._controller.isVirtualMode(); var isAppendMode = this._controller.isAppendMode(); if (e && e.changes) { fireChanged(this, callBase, e) } else if (!this.option(NEW_SCROLLING_MODE) && (isVirtualMode || isAppendMode)) { var beginPageIndex = getBeginPageIndex(this); if (beginPageIndex >= 0) { if (isVirtualMode && beginPageIndex + this._cache.length !== dataOptions.pageIndex() && beginPageIndex - 1 !== dataOptions.pageIndex()) { lastCacheLength = 0; this._cache = [] } if (isAppendMode) { if (0 === dataOptions.pageIndex()) { this._cache = [] } else if (dataOptions.pageIndex() < getEndPageIndex(this)) { fireChanged(this, callBase, { changeType: "append", items: [] }); return } } } var cacheItem = { pageIndex: dataOptions.pageIndex(), itemsLength: dataOptions.items(true).length, itemsCount: this.itemsCount(true) }; if (this.option("scrolling.removeInvisiblePages") && isVirtualMode) { removeInvisiblePages = this._cache.length > Math.max(getPreloadPageCount(this) + (this.option("scrolling.preloadEnabled") ? 1 : 0), 2) } else { processDelayChanged(this, callBase, { isDelayed: true }) } var removeCacheItem; if (beginPageIndex === dataOptions.pageIndex() + 1) { if (removeInvisiblePages) { removeCacheItem = this._cache.pop() } changeType = "prepend"; this._cache.unshift(cacheItem) } else { if (removeInvisiblePages) { removeCacheItem = this._cache.shift() } changeType = "append"; this._cache.push(cacheItem) } var isDelayChanged = isVirtualMode && 0 === lastCacheLength && needTwoPagesLoading(this); processChanged(this, callBase, this._cache.length > 1 ? changeType : void 0, isDelayChanged, removeCacheItem); this._delayDeferred = this.load().done((function() { if (processDelayChanged(_this2, callBase)) { _this2.load() } })) } else { processChanged(this, callBase, e) } }; _proto.getDelayDeferred = function() { return this._delayDeferred }; _proto.itemsCount = function(isBase) { var itemsCount = 0; var isVirtualMode = this._controller.isVirtualMode(); if (!isBase && isVirtualMode) { this._cache.forEach((function(cacheItem) { itemsCount += cacheItem.itemsCount })) } else { itemsCount = this._dataOptions.itemsCount() } return itemsCount }; _proto.virtualItemsCount = function() { var pageIndex = getBeginPageIndex(this); if (pageIndex < 0) { pageIndex = this._dataOptions.pageIndex() } var beginItemsCount = pageIndex * this._dataOptions.pageSize(); var itemsCount = this._cache.length * this._dataOptions.pageSize(); var endItemsCount = Math.max(0, this._dataOptions.totalItemsCount() - itemsCount - beginItemsCount); return { begin: beginItemsCount, end: endItemsCount } }; _proto.reset = function() { this._loadingPageIndexes = {}; this._cache = [] }; return VirtualDataLoader }(); exports.VirtualDataLoader = VirtualDataLoader;