📄 bufferedgridview.js
字号:
} if(!rowEl){ return; } var c = this.scroller.dom; return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()]; }, /** * Checks if the passed argument <tt>cursor</tt> lays within a renderable * area. The area is renderable, if the sum of cursor and the visibleRows * property does not exceed the current upper buffer limit. * * If this method returns <tt>true</tt>, it's basically save to re-render * the view with <tt>cursor</tt> as the absolute position in the model * as the first visible row. * * @param {Number} cursor The absolute position of the row in the data model. * * @return {Boolean} <tt>true</tt>, if the row can be rendered, otherwise * <tt>false</tt> * */ isInRange : function(rowIndex) { var lastRowIndex = Math.min(this.ds.totalLength-1, rowIndex + this.visibleRows); return (rowIndex >= this.bufferRange[0]) && (lastRowIndex <= this.bufferRange[1]); }, /** * Calculates the bufferRange start index for a buffer request * * @param {Boolean} inRange If the index is within the current buffer range * @param {Number} index The index to use as a reference for the calculations * @param {Boolean} down Wether the calculation was requested when the user scrolls down */ getPredictedBufferIndex : function(index, inRange, down) { if (!inRange) { return Math.max(0, index-(2*this.nearLimit)); } if (!down) { return Math.max(0, (index-this.ds.bufferSize)+this.visibleRows); } if (down) { return Math.max(0, Math.min(index, this.ds.totalLength-this.ds.bufferSize)); } }, /** * Updates the table view. Removes/appends rows as needed and fetches the * cells content out of the available store. If the needed rows are not within * the buffer, the method will advise the store to update it's contents. * * The method puts the requested cursor into the queue if a previously called * buffering is in process. * * @param {Number} cursor The row's position, absolute to it's position in the * data model * */ updateLiveRows: function(index, forceRepaint, forceReload) { this.fireEvent('cursormove', this, index, Math.min(this.ds.totalLength, this.visibleRows), this.ds.totalLength); var inRange = this.isInRange(index); if (this.isBuffering && this.isPrebuffering) { if (inRange) { this.replaceLiveRows(index); } else { this.showLoadMask(true); } } if (this.isBuffering) { this.requestQueue = index; return; } var lastIndex = this.lastIndex; this.lastIndex = index; var inRange = this.isInRange(index); var down = false; if (inRange && forceReload !== true) { // repaint the table's view this.replaceLiveRows(index, forceRepaint); // lets decide if we can void this method or stay in here for // requesting a buffer update if (index > lastIndex) { // scrolling down down = true; var totalCount = this.ds.totalLength; // while scrolling, we have not yet reached the row index // that would trigger a re-buffer if (index+this.visibleRows+this.nearLimit < this.bufferRange[1]) { return; } // If we have already buffered the last range we can ever get // by the queried data repository, we don't need to buffer again. // This basically means that a re-buffer would only occur again // if we are scrolling up. if (this.bufferRange[1] >= totalCount) { return; } } else if (index < lastIndex) { // scrolling up down = false; // We are scrolling up in the first buffer range we can ever get // Re-buffering would only occur upon scrolling down. if (this.bufferRange[0] <= 0) { return; } // if we are scrolling up and we are moving in an acceptable // buffer range, lets return. if (index - this.nearLimit > this.bufferRange[0]) { return; } } else { return; } this.isPrebuffering = true; } // prepare for rebuffering this.isBuffering = true var bufferOffset = this.getPredictedBufferIndex(index, inRange, down); var fetchSize = this.ds.bufferSize; if (!inRange) { this.showLoadMask(true); } this.fireEvent('beforebuffer', this, this.ds, index, this.visibleRows, this.ds.totalLength); this.ds.suspendEvents(); var sInfo = this.ds.sortInfo; var params = {}; Ext.apply(params, this.ds.lastOptions); params.start = bufferOffset; params.limit = this.ds.bufferSize; if (sInfo) { params.dir = sInfo.direction; params.sort = sInfo.field; } this.ds.load({ callback : this.liveBufferUpdate, scope : this, params : params }); this.ds.resumeEvents(); }, /** * Shows this' view own load mask to indicate that a large amount of buffer * data was requested by the store. * @param {Boolean} show <tt>true</tt> to show the load mask, otherwise * <tt>false</tt> */ showLoadMask : function(show) { if (this.loadMask == null) { if (show) { this.loadMask = new Ext.LoadMask(this.mainBody.dom.parentNode.parentNode, this.loadMaskConfig); } else { return; } } if (show) { this.loadMask.show(); } else { this.loadMask.hide(); } }, /** * Renders the table body with the contents of the model. The method will * prepend/ append rows after removing from either the end or the beginning * of the table DOM to reduce expensive DOM calls. * It will also take care of rendering the rows selected, taking the property * <tt>bufferedSelections</tt> of the {@link BufferedRowSelectionModel} into * account. * Instead of calling this method directly, the <tt>updateLiveRows</tt> method * should be called which takes care of rebuffering if needed, since this method * will behave erroneous if data of the buffer is requested which may not be * available. * * @param {Number} cursor The position of the data in the model to start * rendering. * * @param {Boolean} forceReplace <tt>true</tt> for recomputing the DOM in the * view, otherwise <tt>false</tt>. */ // private replaceLiveRows : function(cursor, forceReplace) { var spill = cursor-this.lastRowIndex; if (spill == 0 && forceReplace !== true) { return; } // decide wether to prepend or append rows // if spill is negative, we are scrolling up. Thus we have to prepend // rows. If spill is positive, we have to append the buffers data. var append = spill > 0; // abs spill for simplyfiying append/prepend calculations spill = Math.abs(spill); // adjust cursor to the buffered model index var cursorBuffer = cursor-this.bufferRange[0]; // we can skip checking for append or prepend if the spill is larger than // visibleRows. We can paint the whole rows new then- if (spill >= this.visibleRows || spill == 0) { this.mainBody.update(this.renderRows( cursorBuffer, cursorBuffer+this.visibleRows-1 )); } else { if (append) { this.removeRows(0, spill-1); var html = this.renderRows(cursorBuffer+this.visibleRows-spill, cursorBuffer+this.visibleRows-1); Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); } else { this.removeRows(this.visibleRows-spill, this.visibleRows-1); var html = this.renderRows(cursorBuffer, cursorBuffer+spill-1); Ext.DomHelper.insertHtml('beforeBegin', this.mainBody.dom.firstChild, html); } } this.processRows(0, undefined, true); this.lastRowIndex = cursor; }, /** * Adjusts the scroller height to make sure each row in the dataset will be * can be displayed, no matter which value the current height of the grid * component equals to. */ // protected adjustBufferInset : function() { var g = this.grid, ds = g.store; var c = g.getGridEl(); var scrollbar = this.cm.getTotalWidth()+this.scrollOffset > c.getSize().width; // adjust the height of the scrollbar this.liveScroller.dom.style.height = this.liveScroller.dom.parentNode.offsetHeight + (Ext.isGecko ? ((ds.totalLength > 0 && scrollbar) ? - this.horizontalScrollOffset : 0) : (((ds.totalLength > 0 && scrollbar) ? 0 : this.horizontalScrollOffset)))+"px"; if (this.rowHeight == -1) { return; } if (ds.totalLength <= this.visibleRows) { this.liveScrollerInset.style.height = "0px"; return; } var height = this.rowHeight*ds.totalLength; height += (c.getSize().height-(this.visibleRows*this.rowHeight)); if (scrollbar) { height -= this.horizontalScrollOffset; } this.liveScrollerInset.style.height = (height)+"px"; }, /** * Recomputes the number of visible rows in the table based upon the height * of the component. The method adjusts the <tt>rowIndex</tt> property as * needed, if the sum of visible rows and the current row index exceeds the * number of total data available. */ // protected adjustVisibleRows : function() { if (this.rowHeight == -1) { if (this.getRows()[0]) { this.rowHeight = this.getRows()[0].offsetHeight; } else { return; } } var g = this.grid, ds = g.store; var c = g.getGridEl(); var cm = this.cm; var size = c.getSize(true); var vh = size.height; var vw = size.width-this.scrollOffset; // horizontal scrollbar shown? if (cm.getTotalWidth() > vw) { // yes! vh -= this.horizontalScrollOffset; } vh -= this.mainHd.getHeight(); var visibleRows = Math.max(1, Math.floor(vh/this.rowHeight)); if (this.visibleRows == visibleRows) { return; } this.visibleRows = visibleRows; var totalLength = ds.totalLength; if (this.rowIndex + visibleRows > totalLength) { this.rowIndex = Math.max(0, ds.totalLength-this.visibleRows); this.lastRowIndex = this.rowIndex; this.updateLiveRows(this.rowIndex, true); } else { this.updateLiveRows(this.rowIndex, true); } }, adjustScrollerPos : function(pixels, suspendEvent) { var liveScroller = this.liveScroller; if (suspendEvent === true) { liveScroller.un('scroll', this.onLiveScroll, this); } liveScroller.dom.scrollTop += pixels; if (suspendEvent === true) { liveScroller.dom.scrollTop = liveScroller.dom.scrollTop; liveScroller.on('scroll', this.onLiveScroll, this); } } });
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -