📄 bufferedgridview.js
字号:
this.adjustVisibleRows(); this.adjustBufferInset(); } // rows get added before the first row in the view else if (len == this.visibleRows && index <= this.rowIndex-this.bufferRange[0]) { this.fireEvent("beforerowsinserted", this, start, end); this.liveScroller.un('scroll', this.onLiveScroll, this); this.rowIndex += recordLen; this.lastRowIndex = this.rowIndex; this.adjustVisibleRows(); this.adjustBufferInset(); this.adjustScrollerPos(this.rowHeight*recordLen, true); this.fireEvent("rowsinserted", this, start, end); this.processRows(); this.fireEvent('cursormove', this, this.rowIndex, Math.min(this.ds.totalLength, this.visibleRows), this.ds.totalLength); } // rows get added somewhere IN the current view else if ((len < this.visibleRows ) || index > this.rowIndex-this.bufferRange[0]) { firstRow = index; lastRow = Math.min(end, this.rowIndex+this.visibleRows-1) - this.bufferRange[0]; this.insertRows(ds, firstRow, lastRow); this.adjustVisibleRows(); this.adjustBufferInset(); } },// {{{ ----------------------store listeners------------------------------------ /** * This callback for the store's "beforeload" event will adjust the start * position and the limit of the data in the model to fetch. It is guaranteed * that this method will only be called when the store initially loads, * remeote-sorts or reloads. * All other load events will be suspended when the view requests buffer data. * See {updateLiveRows}. * * @param {Ext.data.Store} store The store the Grid Panel uses * @param {Object} options The configuration object for the proxy that loads * data from the server */ onBeforeLoad : function(store, options) { if (!options.params) { options.params = {start : 0, limit : this.ds.bufferSize}; } else { options.params.start = 0; options.params.limit = this.ds.bufferSize; } options.scope = this; options.callback = function(){this.reset(false);}; return true; }, /** * Method is used as a callback for the load-event of the attached data store. * Adjusts the buffer inset based upon the <tt>totalCount</tt> property * returned by the response. * Overwrites the parent's implementation. */ onLoad : function(o1, o2, options) { this.adjustBufferInset(); }, /** * This will be called when the data in the store has changed, i.e. a * re-buffer has occured. If the table was not rendered yet, a call to * <tt>refresh</tt> will initially render the table, which DOM elements will * then be used to re-render the table upon scrolling. * */ // private onDataChange : function(store) { this.updateHeaderSortState(); }, /** * A callback for the store when new data has been buffered successfully. * If the current row index is not within the range of the newly created * data buffer or another request to new data has been made while the store * was loading, new data will be re-requested. * * Additionally, if there are any rows that have been selected which were not * in the data store, the method will request the pending selections from * the grid's selection model and add them to the selections if available. * This is because the component assumes that a user who scrolls through the * rows and updates the view's buffer during scrolling, can check the selected * rows which come into the view for integrity. It is up to the user to * deselect those rows not matchuing the selection. * Additionally, if the version of the store changes during various requests * and selections are still pending, the versionchange event of the store * can delete the pending selections after a re-bufer happened and before this * method was called. * */ // private liveBufferUpdate : function(o1, options, o2) { this.fireEvent('buffer', this, this.ds, this.rowIndex, Math.max(this.visibleRows, this.getRows().length), this.ds.getTotalCount()); this.isBuffering = false; this.isPrebuffering = false; this.showLoadMask(false); // we have to stay in sync with rows that may have been skipped while // the request was loading. this.bufferRange = [ options.params.start, options.params.start+options.params.limit ]; var pendingSelections = this.grid.selModel.getPendingSelections(false); for (var i = 0, max_i = pendingSelections.length; i < max_i; i++) { this.grid.selModel.clearPendingSelection(pendingSelections[i]); } if (this.isInRange(this.rowIndex)) { this.replaceLiveRows(this.rowIndex); } else { this.updateLiveRows(this.rowIndex); } if (this.requestQueue >= 0) { var offset = this.requestQueue; this.requestQueue = -1; this.updateLiveRows(offset); } }, // {{{ ----------------------scroll listeners------------------------------------ /** * Handles mousewheel event on the table's body. This is neccessary since the * <tt>liveScroller</tt> element is completely detached from the table's body. * * @param {Ext.EventObject} e The event object */ handleWheel : function(e) { if (this.rowHeight == -1) { e.stopEvent(); return; } var d = e.getWheelDelta(); this.adjustScrollerPos(-(d*this.rowHeight)); e.stopEvent(); }, /** * Handles scrolling through the grid. Since the grid is fixed and rows get * removed/ added subsequently, the only way to determine the actual row in * view is to measure the <tt>scrollTop</tt> property of the <tt>liveScroller</tt>'s * DOM element. * */ onLiveScroll : function() { var scrollTop = this.liveScroller.dom.scrollTop; var pixelsSkipped = scrollTop-this.lastScrollPos; var rowsSkipped = Math.floor(pixelsSkipped/this.rowHeight); // happens when no scrolling actually happened if (pixelsSkipped == 0) { return; } var cursor = Math.floor((scrollTop)/this.rowHeight); this.rowIndex = cursor; // the lastRowIndex will be set when refreshing the view finished if (cursor == this.lastRowIndex) { return; } this.updateLiveRows(cursor, rowsSkipped); this.lastScrollPos = this.liveScroller.dom.scrollTop; }, // {{{ --------------------------helpers---------------------------------------- // private refreshRow : function(record) { var ds = this.ds, index; if(typeof record == 'number'){ index = record; record = ds.getAt(index); }else{ index = ds.indexOf(record); } var viewIndex = index + this.bufferRange[0]; if (viewIndex < this.rowIndex || viewIndex >= this.rowIndex + this.visibleRows) { this.fireEvent("rowupdated", this, viewIndex, record); return; } this.insertRows(ds, index, index, true); //this.getRow(index).rowIndex = index; //this.onRemove(ds, record, index+1, true); this.fireEvent("rowupdated", this, viewIndex, record); }, /** * Overwritten so the rowIndex can be changed to the absolute index. * * If the third parameter equals to <tt>true</tt>, the method will also * repaint the selections. */ // private processRows : function(startRow, skipStripe, paintSelections) { skipStripe = skipStripe || !this.grid.stripeRows; // we will always process all rows in the view startRow = 0; var rows = this.getRows(); var cls = ' x-grid3-row-alt '; var cursor = this.rowIndex; var index = 0; var selections = this.grid.selModel.selections; var ds = this.ds; for(var i = startRow, len = rows.length; i < len; i++){ index = i+cursor; var row = rows[i]; // changed! row.rowIndex = index; if (paintSelections == true) { if (this.grid.selModel.bufferedSelections[index] === true) { this.addRowClass(i, "x-grid3-row-selected"); selections.add(ds.getAt(index-this.bufferRange[0])); } this.fly(row).removeClass("x-grid3-row-over"); } if(!skipStripe){ var isAlt = ((i+1) % 2 == 0); var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1; if(isAlt == hasAlt){ continue; } if(isAlt){ row.className += " x-grid3-row-alt"; }else{ row.className = row.className.replace("x-grid3-row-alt", ""); } } } }, /** * API only, since the passed arguments are the indexes in the buffer store. * However, the method will try to compute the indexes so they might match * the indexes of the records in the underlying data model. * */ // private insertRows : function(dm, firstRow, lastRow, isUpdate) { var viewIndexFirst = firstRow + this.bufferRange[0]; var viewIndexLast = lastRow + this.bufferRange[0]; if (!isUpdate) { this.fireEvent("beforerowsinserted", this, viewIndexFirst, viewIndexLast); } // first off, remove the rows at the bottom of the view to match the // visibleRows value and to not cause any spill in the DOM if (isUpdate !== true && this.getRows().length == this.visibleRows) { this.removeRows((this.visibleRows-1)-(lastRow-firstRow), this.visibleRows-1); } if (isUpdate) { this.removeRows(viewIndexFirst-this.rowIndex, viewIndexLast-this.rowIndex); } var html = this.renderRows(firstRow, lastRow); var before = this.getRow(firstRow-(this.rowIndex-this.bufferRange[0])); if (before) { Ext.DomHelper.insertHtml('beforeBegin', before, html); } else { Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); } if (isUpdate === true) { var rows = this.getRows(); var cursor = this.rowIndex; for (var i = 0, max_i = rows.length; i < max_i; i++) { rows[i].rowIndex = cursor+i; } } if (!isUpdate) { this.fireEvent("rowsinserted", this, viewIndexFirst, viewIndexLast); this.processRows(firstRow); } }, /** * Focuses the specified cell. * @param {Number} row The row index * @param {Number} col The column index */ focusCell : function(row, col, hscroll) { var xy = this.ensureVisible(row, col, hscroll); if (!xy) { return; } this.focusEl.setXY(xy); if(Ext.isGecko){ this.focusEl.focus(); }else{ this.focusEl.focus.defer(1, this.focusEl); } }, /** * Makes sure that the requested /row/col is visible in the viewport. * The method may invoke a request for new buffer data and triggers the * scroll-event of the <tt>liveScroller</tt> element. * */ // private ensureVisible : function(row, col, hscroll) { if(typeof row != "number"){ row = row.rowIndex; } if(row < 0 || row >= this.ds.totalLength){ return; } col = (col !== undefined ? col : 0); var rowInd = row-this.rowIndex; if (row >= this.rowIndex+this.visibleRows) { this.adjustScrollerPos(((row-(this.rowIndex+this.visibleRows))+1)*this.rowHeight); } else if (row < this.rowIndex) { this.adjustScrollerPos((rowInd)*this.rowHeight); } var rowInd = rowInd < 0 ? row : rowInd; var rowEl = this.getRow(rowInd), cellEl; if(!(hscroll === false && col === 0)){ while(this.cm.isHidden(col)){ col++; } cellEl = this.getCell(row-this.rowIndex, col);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -