]>
git.proxmox.com Git - sencha-touch.git/blob - src/src/data/plugin/Buffered.js
2 * @class Ext.data.plugin.Buffered
5 Ext
.define('Ext.data.plugin.Buffered', {
6 alias
: 'plugin.storebuffered',
11 'Ext.util.BufferedCollection'
18 * @cfg {Number} trailingBufferZone
19 * When {@link #buffered}, the number of extra records to keep cached on the trailing side of scrolling buffer
20 * as scrolling proceeds. A larger number means fewer replenishments from the server.
22 trailingBufferZone
: 25,
25 * @cfg {Number} leadingBufferZone
26 * When {@link #buffered}, the number of extra rows to keep cached on the leading side of scrolling buffer
27 * as scrolling proceeds. A larger number means fewer replenishments from the server.
29 leadingBufferZone
: 50,
32 * @cfg {Number} purgePageCount
33 * *Valid only when used with a {@link Ext.data.Store#buffered buffered} Store.*
35 * The number of pages *additional to the required buffered range* to keep in the prefetch cache before purging least recently used records.
37 * For example, if the height of the view area and the configured {@link #trailingBufferZone} and {@link #leadingBufferZone} require that there
38 * are three pages in the cache, then a `purgePageCount` of 5 ensures that up to 8 pages can be in the page cache any any one time.
40 * A value of 0 indicates to never purge the prefetched data.
44 // Number of records to load into a buffered grid before it has been bound to a view of known size
47 bufferedCollection
: {}
50 init: function(store
) {
52 this.pageRequests
= {};
55 applyBufferedCollection: function(config
) {
56 return Ext
.factory(config
, Ext
.util
.BufferedCollection
, this.getBufferedCollection());
59 updateBufferedCollection: function(collection
) {
60 var store
= this.getStore();
62 Ext
.destroy(store
.data
);
63 store
.data
= collection
;
67 updateStore: function(store
) {
69 store
.setRemoteSort(true);
70 store
.setRemoteFilter(true);
71 store
.setRemoteGroup(true);
72 store
.setPageSize(this.getViewSize());
73 this.updateBufferedCollection(this.getBufferedCollection());
76 Ext
.Function
.interceptBefore(store
, 'add', function() {
78 msg
: 'add method may not be called on a buffered store'
84 load
: Ext
.Function
.bind(this.load
, this),
90 updateViewSize: function(viewSize
) {
91 var store
= this.getStore();
93 store
.setPageSize(viewSize
);
94 this.getBufferedCollection().setPageSize(viewSize
);
98 requestRange: function(start
, end
, callback
, scope
) {
99 if (this.isRangeCached(start
, end
)) {
100 callback
.call(scope
|| this, this.getBufferedCollection().getRange(start
, end
));
111 load: function(options
, scope
) {
112 var store
= this.getStore(),
113 currentPage
= store
.currentPage
,
114 viewSize
= this.getViewSize();
116 options
= options
|| {};
118 if (Ext
.isFunction(options
)) {
125 Ext
.applyIf(options
, {
126 sorters
: store
.getSorters(),
127 filters
: store
.getFilters(),
128 grouper
: store
.getGrouper(),
131 start
: (currentPage
- 1) * viewSize
,
136 model
: store
.getModel()
139 this.loadPrefetch(options
);
142 loadPrefetch: function(options
) {
144 startIndex
= options
.start
,
145 endIndex
= options
.start
+ options
.limit
- 1,
146 trailingBufferZone
= me
.getTrailingBufferZone(),
147 leadingBufferZone
= me
.getLeadingBufferZone(),
148 startPage
= me
.getPageFromRecordIndex(Math
.max(startIndex
- trailingBufferZone
, 0)),
149 endPage
= me
.getPageFromRecordIndex(endIndex
+ leadingBufferZone
),
150 bufferedCollection
= me
.getBufferedCollection(),
151 store
= me
.getStore(),
152 prefetchOptions
= Ext
.apply({}, options
),
153 waitForRequestedRange
, totalCount
, i
, records
;
155 // Wait for the viewable range to be available
156 waitForRequestedRange = function() {
157 if (me
.isRangeCached(startIndex
, endIndex
)) {
158 store
.loading
= false;
160 bufferedCollection
.un('pageadded', waitForRequestedRange
);
161 records
= bufferedCollection
.getRange(startIndex
, endIndex
);
163 if (options
.callback
) {
164 options
.callback
.call(options
.scope
|| me
, records
, startIndex
, endIndex
, options
);
169 delete prefetchOptions
.callback
;
171 store
.on('prefetch', function(store
, records
, successful
) {
173 totalCount
= store
.getTotalCount();
175 bufferedCollection
.on('pageadded', waitForRequestedRange
);
177 // As soon as we have the size of the dataset, ensure we are not waiting for more than can ever arrive,
178 endIndex
= Math
.min(endIndex
, totalCount
- 1);
180 // And make sure we never ask for pages beyond the end of the dataset.
181 endPage
= me
.getPageFromRecordIndex(Math
.min(endIndex
+ leadingBufferZone
, totalCount
- 1));
183 for (i
= startPage
+ 1; i
<= endPage
; ++i
) {
184 me
.prefetchPage(i
, prefetchOptions
);
188 }, this, {single
: true});
190 me
.prefetchPage(startPage
, prefetchOptions
);
194 * Prefetches a page of data.
195 * @param {Number} page The page to prefetch
196 * @param {Object} options (Optional) config object, passed into the Ext.data.Operation object before loading.
197 * See {@link #method-load}
199 prefetchPage: function(page
, options
) {
201 viewSize
= me
.getViewSize();
203 // Copy options into a new object so as not to mutate passed in objects
204 me
.prefetch(Ext
.applyIf({
206 start
: (page
- 1) * viewSize
,
212 * Prefetches data into the store using its configured {@link #proxy}.
213 * @param {Object} options (Optional) config object, passed into the Ext.data.Operation object before loading.
214 * See {@link #method-load}
216 prefetch: function(options
) {
218 pageSize
= me
.getViewSize(),
219 store
= me
.getStore(),
222 // Always get whole pages.
224 options
.page
= me
.getPageFromRecordIndex(options
.start
);
225 options
.start
= (options
.page
- 1) * pageSize
;
226 options
.limit
= Math
.ceil(options
.limit
/ pageSize
) * pageSize
;
229 // Currently not requesting this page, then request it...
230 if (!me
.pageRequests
[options
.page
]) {
231 // Copy options into a new object so as not to mutate passed in objects
232 options
= Ext
.applyIf({
234 sorters
: store
.getSorters(),
235 filters
: store
.getFilters(),
236 grouper
: store
.getGrouper()
239 operation
= Ext
.create('Ext.data.Operation', options
);
241 if (store
.fireEvent('beforeprefetch', me
, operation
) !== false) {
242 me
.pageRequests
[options
.page
] = store
.getProxy().read(operation
, me
.onProxyPrefetch
, me
);
250 * Called after the configured proxy completes a prefetch operation.
252 * @param {Ext.data.Operation} operation The operation that completed
254 onProxyPrefetch: function(operation
) {
256 resultSet
= operation
.getResultSet(),
257 records
= operation
.getRecords(),
258 successful
= operation
.wasSuccessful(),
259 store
= me
.getStore(),
260 bufferedCollection
= me
.getBufferedCollection(),
261 page
= operation
.getPage(),
265 total
= resultSet
.getTotal();
267 if (total
!== store
.getTotalCount()) {
268 store
.setTotalCount(total
);
269 bufferedCollection
.setTotalCount(total
);
271 store
.fireEvent('totalcountchange', store
, total
);
275 store
.loading
= false;
278 me
.cachePage(records
, page
);
281 store
.fireEvent('prefetch', store
, records
, successful
, operation
);
283 //this is a callback that would have been passed to the 'read' function and is optional
284 Ext
.callback(operation
.callback
, operation
.scope
|| me
, [records
, operation
, successful
]);
288 * Caches the records in the prefetch and stripes them with their server-side
291 * @param {Ext.data.Model[]} records The records to cache
292 * @param {Ext.data.Operation} page The associated operation
294 cachePage: function(records
, page
) {
296 bufferedCollection
= me
.getBufferedCollection(),
297 ln
= records
.length
, i
;
299 // Add the fetched page into the pageCache
300 for (i
= 0; i
< ln
; i
++) {
304 bufferedCollection
.addPage(page
, records
);
308 * Determines the page from a record index
309 * @param {Number} index The record index
310 * @return {Number} The page the record belongs to
312 getPageFromRecordIndex: function(index
) {
313 return Math
.floor(index
/ this.getViewSize()) + 1;
317 * Determines if the passed range is available in the page cache.
319 * @param {Number} start The start index
320 * @param {Number} end The end index in the range
322 isRangeCached: function(start
, end
) {
323 return this.getBufferedCollection().hasRange(start
, end
);