- * Query the cached records in this Store using a filtering function. The specified function
- * will be called with each record in this Store. If the function returns <tt>true</tt> the record is
- * included in the results.
- * @param {Function} fn The function to be called. It will be passed the following parameters:<ul>
- * <li><b>record</b> : Ext.data.Record<p class="sub-desc">The {@link Ext.data.Record record}
- * to test for filtering. Access field values using {@link Ext.data.Record#get}.</p></li>
- * <li><b>id</b> : Object<p class="sub-desc">The ID of the Record passed.</p></li>
- * </ul>
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to this Store.
- * @return {MixedCollection} Returns an Ext.util.MixedCollection of the matched records
- **/
- queryBy : function(fn, scope){
- var data = this.snapshot || this.data;
- return data.filterBy(fn, scope||this);
+ * Guarantee a specific range, this will load the store with a range (that
+ * must be the pageSize or smaller) and take care of any loading that may
+ * be necessary.
+ */
+ guaranteeRange: function(start, end, cb, scope) {
+ //<debug>
+ if (start && end) {
+ if (end - start > this.pageSize) {
+ Ext.Error.raise({
+ start: start,
+ end: end,
+ pageSize: this.pageSize,
+ msg: "Requested a bigger range than the specified pageSize"
+ });
+ }
+ }
+ //</debug>
+
+ end = (end > this.totalCount) ? this.totalCount - 1 : end;
+
+ var me = this,
+ i = start,
+ prefetchData = me.prefetchData,
+ range = [],
+ startLoaded = !!prefetchData.getByKey(start),
+ endLoaded = !!prefetchData.getByKey(end),
+ startPage = me.getPageFromRecordIndex(start),
+ endPage = me.getPageFromRecordIndex(end);
+
+ me.cb = cb;
+ me.scope = scope;
+
+ me.requestStart = start;
+ me.requestEnd = end;
+ // neither beginning or end are loaded
+ if (!startLoaded || !endLoaded) {
+ // same page, lets load it
+ if (startPage === endPage) {
+ me.mask();
+ me.prefetchPage(startPage, {
+ //blocking: true,
+ callback: me.onWaitForGuarantee,
+ scope: me
+ });
+ // need to load two pages
+ } else {
+ me.mask();
+ me.prefetchPage(startPage, {
+ //blocking: true,
+ callback: me.onWaitForGuarantee,
+ scope: me
+ });
+ me.prefetchPage(endPage, {
+ //blocking: true,
+ callback: me.onWaitForGuarantee,
+ scope: me
+ });
+ }
+ // Request was already satisfied via the prefetch
+ } else {
+ me.onGuaranteedRange();
+ }
+ },
+
+ // because prefetchData is stored by index
+ // this invalidates all of the prefetchedData
+ sort: function() {
+ var me = this,
+ prefetchData = me.prefetchData,
+ sorters,
+ start,
+ end,
+ range;
+
+ if (me.buffered) {
+ if (me.remoteSort) {
+ prefetchData.clear();
+ me.callParent(arguments);
+ } else {
+ sorters = me.getSorters();
+ start = me.guaranteedStart;
+ end = me.guaranteedEnd;
+
+ if (sorters.length) {
+ prefetchData.sort(sorters);
+ range = prefetchData.getRange();
+ prefetchData.clear();
+ me.cacheRecords(range);
+ delete me.guaranteedStart;
+ delete me.guaranteedEnd;
+ me.guaranteeRange(start, end);
+ }
+ me.callParent(arguments);
+ }
+ } else {
+ me.callParent(arguments);
+ }
+ },
+
+ // overriden to provide striping of the indexes as sorting occurs.
+ // this cannot be done inside of sort because datachanged has already
+ // fired and will trigger a repaint of the bound view.
+ doSort: function(sorterFn) {
+ var me = this;
+ if (me.remoteSort) {
+ //the load function will pick up the new sorters and request the sorted data from the proxy
+ me.load();
+ } else {
+ me.data.sortBy(sorterFn);
+ if (!me.buffered) {
+ var range = me.getRange(),
+ ln = range.length,
+ i = 0;
+ for (; i < ln; i++) {
+ range[i].index = i;
+ }
+ }
+ me.fireEvent('datachanged', me);
+ }