PDA

View Full Version : Custom proxy to read from another store



ruslan.talpa
24 Oct 2011, 6:41 AM
Has anyone tried o write a custom proxy which get's it's data from another store?
It would be something like
Store2 <- CustomProxy -> Store1

Store1 would be a store with rest proxy
Store2 would be a subset of Store1 (additional filters, sorters)

This approach, in my opinion would allow an application to have one BIG store, with no filters, that communicates with the backend and a lot of small stores, with different kind of filters and sorters that can be used for different views.

This would solve the problem (which i see a lot of ppl have) of having one store tied to multiple views.
since the core problem they are trying to solve is not to load the same remote data multiple times.

Thanks.

skirtle
24 Oct 2011, 10:32 AM
I haven't seen anyone attempt this but it is an interesting thought.

I guess you'd base it on the copy() method for a record?

http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model-method-copy

I can think of a couple of other ways to achieve a similar affect. First, you could just clone the store. I don't believe there's a single method to do this but it should be fairly trivial to loop over the records and copy() them all. Another way to do it, similar to the one you've proposed, might be to try to write to a MemoryProxy from the initial store and then use it for all the other stores.

The end results for these 3 techniques aren't all exactly equivalent so I can see arguments in favour of each of them.

ruslan.talpa
26 Oct 2011, 12:41 AM
28880

This is a first try.
I managed to create a proxy that can read data from another (server) store.
This allows me to have one "master" store that communicates with the server and two other stores that get the data from this store without communication to the server and i can add custom filters on these two stores without affecting the main store.

To each of the stores i attached a grid to see the result.

To have this behavior i needed a special proxy and a special data store ( which only overrides the setProxy function in order to pass a reference to itself )

It would also be interesting to modify the Ext.data.Model (or whichever class is responsible to returning stores when using associations) so that the stores returned are the special kind of stores described above so that we do not end up we a lot of different independent stores when using associations. I think this the desired behavior in 90% of the cases when using associations.

Maybe Ed Spencer can take a look at this thread (since he is responsible for the data package) and think about implementing this idea in future releases.

PS: although the add/update/destroy are implemented they were not tested so they might not work.

ruslan.talpa
26 Oct 2011, 1:03 AM
Here is the code




/**
* Application code
*
*/


Ext.onReady(function(){


main_store = Ext.create( 'Test.store.Projects' );

store1 = Ext.create('Test.data.Store', {
model: "Test.model.Project",
proxy: {
type: 'store',
sourceStore: main_store
},
filters: [
{
property: 'name',
value : /1/
}
]
});

store2 = Ext.create('Test.data.Store', {
model: "Test.model.Project",
proxy: {
type: 'store',
sourceStore: 'Test.store.Projects'
},
filters: [
{
property: 'name',
value : /2/
}
]
});

Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: main_store,
title: 'Projects main store',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name' }
]
});

Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: store1,
title: 'Projects store1 with a filter /1/ on name',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name' }
]
});

Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: store2,
title: 'Projects store2 with a filter /2/ on name',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name' }
]
});
});


/**
* Define the classes we are using
*/
Ext.define('Test.data.proxy.Store', {

extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.store',
alternateClassName: ['Test.data.StoreProxy'],


constructor: function(config) {
//call the parent cosntructor
config = config || {};
this.callParent([config]);
this.sourceStore = config.sourceStore;
this.setStore( config.store );

if (this.sourceStore === undefined) {
Ext.Error.raise("You have to provide a parent store");
}
this.initialize();
},

initialize: function(){
if( typeof( this.sourceStore ) == 'string' ){
//the store was givven to us by id so let's get it from store manager
this.sourceStore = Ext.data.StoreManager.lookup( this.sourceStore );
if( this.sourceStore === undefined ){ //the parent store was not loaded, let's do that
this.sourceStore = Ext.create(this.sourceStore);
}
}


//refresh our parent store if the source store data changed
this.sourceStore.on('datachanged', function(){
this.store.load();
}, this);
},

proxyCallback: function(records, operation, success){
operation.callback = operation.original_callback;
operation.scope = operation.original_scope;
Ext.callback(operation.store_callback, operation.store_scope || this, [ operation ]);
},


setStore: function( store ){
this.store = store;
},


create: function(operation, callback, scope) {
operation.original_callback = operation.callback;
operation.original_scope = operation.scope;
operation.callback = this.proxyCallback;
operation.scope = this;
operation.store_callback = callback;
operation.store_scope = scope;
return this.sourceStore.getProxy().create(operation, this.sourceStore.onProxyWrite, this.sourceStore);
},


read: function(operation, callback, scope) {
var me = this,
records = [],
count = this.sourceStore.getCount(),
result;

for ( var row = 0; row < count; row++ ) {
records.push( this.sourceStore.getAt( row ) );
}

result = Ext.create('Ext.data.ResultSet', {
total : this.sourceStore.getTotalCount(),
count : count,
records: records,
success: true
});


Ext.apply(operation, {
resultSet: result
});


operation.setCompleted();
operation.setSuccessful();
Ext.callback(callback, scope || me, [operation]);
},


update: function(operation, callback, scope) {
operation.original_callback = operation.callback;
operation.original_scope = operation.scope;
operation.callback = this.proxyCallback;
operation.scope = this;
operation.store_callback = callback;
operation.store_scope = scope;
return this.sourceStore.getProxy().update(operation, this.sourceStore.onProxyWrite, this.sourceStore);
},


destroy: function(operation, callback, scope) {
operation.original_callback = operation.callback;
operation.original_scope = operation.scope;
operation.callback = this.proxyCallback;
operation.scope = this;
operation.store_callback = callback;
operation.store_scope = scope;
this.sourceStore.getProxy().destroy(operation, this.sourceStore.onProxyWrite, this.sourceStore);
}
});


Ext.define('Test.data.Store', {
extend: 'Ext.data.Store',
autoLoad: true,

//override the set proxy method so that we can send to proxy a refference to us
setProxy: function(proxy) {
var me = this;

if (proxy instanceof Ext.data.proxy.Proxy) {
proxy.setModel(me.model);
if( proxy instanceof Test.data.proxy.Store ) {
proxy.setStore( me );
}
} else {
if (Ext.isString(proxy)) {
proxy = {
type: proxy
};
}
Ext.applyIf(proxy, {
model: me.model,
store: me
});

proxy = Ext.createByAlias('proxy.' + proxy.type, proxy);
}

me.proxy = proxy;

return me.proxy;
},
});


Ext.define('Test.model.Project', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
proxy: {
type: 'ajax',
url : 'projects.json',
reader: {
type: 'json',
root: 'projects'
}
}
});


Ext.define('Test.store.Projects', {
extend: 'Ext.data.Store',
model: 'Test.model.Project',
storeId: 'Test.store.Projects',
autoLoad: true
});






And the data projects.json


{
success: true,
projects: [
{ id: 1, name: 'Project 1' },
{ id: 2, name: 'Project 2' },
{ id: 3, name: 'Project 3' }
]
}

ruslan.talpa
26 Oct 2011, 5:02 AM
As expected, the create/update/destroy code does not work quite right yet but it should not be hard to fix.

ruslan.talpa
27 Oct 2011, 11:37 PM
Modified the code so that only the special proxy class is needed, the stores can be normal Ext.data.Store
Also the create/update/remove works now.

Please test in different scenarios and tell me your results.

index.html


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Paymo API SDK Test </title>
<link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-4.0.2a/resources/css/ext-all.css"/>
<script type="text/javascript" src="http://extjs.cachefly.net/ext-4.0.2a/ext-all-debug.js"></script>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
</body>
</html>


test.js


/**
* Application code
*
*/

Ext.onReady(function(){
var main_store, store1, store2;

main_store = Ext.create( 'Test.store.Projects' );

store1 = Ext.create('Ext.data.Store', {
model: "Test.model.Project",
proxy: {
type: 'store',
sourceStore: main_store
},
filters: [
{
property: 'name',
value : /1/
}
]
});

store2 = Ext.create('Ext.data.Store', {
model: "Test.model.Project",
proxy: {
type: 'store',
sourceStore: 'Test.store.Projects'
},
filters: [
{
property: 'name',
value : /2/
}
]
});

main_store.on('datachanged', function(){
console.log('datachanged in main_store');
store2.load();
})

main_store.load({
scope: this,
callback: function(records, operation, success) {

store1.load(function(){

setTimeout(function(){
console.log('adding 2 records to store1');
store1.add( {name: 'Added Project from store1'}, {name: 'And Added Project from store1'} );
store1.sync();
}, 1000);

setTimeout(function(){
console.log('updating one record in store1')
store1.getAt(0).set('name', 'Project 1 updated');
store1.sync();
}, 2000);

setTimeout(function(){
console.log('removing record from store1');
store1.remove(store1.getById(50));
store1.sync();
}, 3000);
});
store2.load();
}
});


Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: main_store,
title: 'Projects main store',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name', width: 300 }
]
});

Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: store1,
title: 'Projects store1 with a filter /1/ on name',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name', width: 300 }
]
});

Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: store2,
title: 'Projects store2 with a filter /2/ on name',
columns: [
{ text: 'Id', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name', width: 300 }
]
});
});


/**
* Define the classes we are using
*/

Ext.define('Test.data.proxy.Store', {
extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.store',
alternateClassName: ['Test.data.StoreProxy'],

constructor: function(config) {
//call the parent cosntructor
config = config || {};
this.callParent([config]);
this.sourceStore = config.sourceStore;

if (this.sourceStore === undefined) {
Ext.Error.raise("You have to provide a parent store");
}
this.initialize();
},

initialize: function(){
if( typeof( this.sourceStore ) == 'string' ){
//the store was givven to us by id so let's get it from store manager
this.sourceStore = Ext.data.StoreManager.lookup( this.sourceStore );
if( this.sourceStore === undefined ){ //the parent store was not loaded, let's do that
this.sourceStore = Ext.create(this.sourceStore);
}
}
},

create: function(operation, callback, scope) {
var originalAutoSync = this.sourceStore.autoSync;
this.sourceStore.autoSync = false;
this.sourceStore.add(operation.getRecords());
this.sourceStore.autoSync = originalAutoSync;
this.writeOperation(operation, callback, scope);
},

read: function(operation, callback, scope) {

var me = this,
records = [],
count = this.sourceStore.getCount(),
result;

for ( var row = 0; row < count; row++ ) {
records.push( this.sourceStore.getAt( row ) );
}

result = Ext.create('Ext.data.ResultSet', {
total : this.sourceStore.getTotalCount(),
count : count,
records: records,
success: true
});

Ext.apply(operation, {
resultSet: result
});

operation.setCompleted();
operation.setSuccessful();
Ext.callback(callback, scope || me, [operation]);
},

update: function(operation, callback, scope) {
this.writeOperation(operation, callback, scope);
},

destroy: function(operation, callback, scope) {
operation.setStarted();
this.sourceStore.remove(operation.getRecords());
},

writeOperation: function(operation, callback, scope) {
var me = this,
autoSyncValue,
options = {},
listeners = {
scope: me,
exception: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
Ext.callback(sourceListeners.exception, this.sourceStore, [batch, operation]);
},
operationcomplete: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
if( sourceListeners.operationcomplete ){
Ext.callback(sourceListeners.operationcomplete, this.sourceStore, [batch, operation]);
}
Ext.callback(callback, scope, [operation]);
},
complete: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
if( sourceListeners.complete ){
Ext.callback(sourceListeners.complete, this.sourceStore, [batch, operation]);
}
//Ext.callback(callback, scope, [operation]);
}
},
records = operation.getRecords();

operation.setStarted();
if (true){ //for now we force the sync since currenctly there is no way to get notified by the sourceStore when this operation is completed
//if (this.sourceStore.autoSync) {
//sync the data back to the server and tell both stores about the result
switch( operation.action ){
case 'create':
options.create = records;
break;
case 'update':
options.update = records;
break;
}
this.sourceStore.getProxy().batch(options, listeners);
}
}
});

Ext.define('Test.model.Project', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
proxy: {
type: 'ajax',
api: {
create: 'addProjects.json',
read: 'projects.json',
update: 'updateProjects.json',
destroy: 'destroyProjects.json',
},
reader: {
type: 'json',
root: 'projects',
successProperty: 'success'
}
}
});

Ext.define('Test.store.Projects', {
extend: 'Ext.data.Store',
model: 'Test.model.Project',
storeId: 'Test.store.Projects'
});


addProjects.json


{
success: true,
projects: [
{ id: 4, name: 'Added Project from store1'},
{ id: 5, name: 'And Added Project from store1'}
]
}


destroyProjects.json


{
success: true
}


updateProjects.json


{
success: true,
projects: [
{ id: 1, name: 'Project 1 updated' }
]
}


projects.json


{
success: true,
projects: [
{ id: 1, name: 'Project 1'},
{ id: 2, name: 'Project 2'},
{ id: 3, name: 'Project 3'},
{ id: 50, name: 'Project 12'}
]
}

skirtle
28 Oct 2011, 11:21 AM
Once you've got this finished I'd advise posting it in the UX forum:

http://www.sencha.com/forum/forumdisplay.php?82

That's where most people would go looking for this kind of thing.

ruslan.talpa
2 Nov 2011, 1:28 AM
New version of the proxy. The sync on the source store is not forced anymore and but the id's of then new records will be updated from the source store when it is synced to the backend




Ext.define('Test.data.proxy.Store', {
extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.store',
alternateClassName: ['Test.data.StoreProxy'],
unsyncedRecords: [],

constructor: function(config) {
//call the parent cosntructor
config = config || {};
this.callParent([config]);
this.sourceStore = config.sourceStore;

if (this.sourceStore === undefined) {
Ext.Error.raise("You have to provide a parent store");
}
this.initialize();
},

initialize: function(){
var me = this;
if( typeof( this.sourceStore ) == 'string' ){
//the store was given to us by id so let's get it from store manager
this.sourceStore = Ext.data.StoreManager.lookup( this.sourceStore );
if( this.sourceStore === undefined ){ //the parent store was not loaded, let's do that
this.sourceStore = Ext.create(this.sourceStore);
}
}
//replace the afterRequest function of the source proxy so that we can listen to the events
if( this.sourceStore.getProxy().afterRequest === Ext.emptyFn){
this.sourceStore.getProxy().afterRequest = this.sourceProxyAfterRequest;
this.sourceStore.getProxy().addEvents( 'afterrequest' );
}

//monitore the operations of the remote store's proxy
this.sourceStore.getProxy().on('afterrequest', this.onSourceStoreProxyOperation, me);

},

sourceProxyAfterRequest: function(request, success){
this.fireEvent('afterrequest', request, success);
},

onSourceStoreProxyOperation: function(request, success){

var me = this,
operation = request.operation,
records = operation.getRecords(),
i, record,
opeartionId;

if( request.action != 'read' && request.records.length ){
opeartionId = request.records[0].operationId;
}

if( opeartionId && this.unsyncedRecords[opeartionId]) { //this is an operation initiated by us

switch (operation.action) {
case 'create':
if (success === true) {
if (operation.wasSuccessful() !== false) {
//we just need to change the record id's in our store
for(i = 0; i < records.length; i++){
record =this.unsyncedRecords[opeartionId].records[i]
record.setId( records[i].getId() );
record.commit();

}
}
}
break;
case 'update':
break;
case 'destroy': //nothing to do on destroy
break;
}
}
},

create: function(operation, callback, scope) {
//since the post to another store in immidiate we behave much liek the web store
var records = operation.records,
length = records.length,
id, record, i,
operationId = Math.floor(Math.random()*100001),
sourceRecords = [];


for(i = 0; i < length; i++){
sourceRecords[i] = records[i].copy();
sourceRecords[i].phantom = true;
sourceRecords[i].operationId = operationId;//carry over the operation id
}



for (i = 0; i < length; i++) {
record = records[i];
if (record.phantom) {
record.phantom = false;
id = Math.floor(Math.random()*100000001) * -1;
} else {
id = record.getId();
}
record.setId(id);
record.commit();
}

this.sourceStore.add(sourceRecords);

operation.setCompleted();
operation.setSuccessful();


if (typeof callback == 'function') {
callback.call(scope || this, operation);
}

//remember this transaction so that later we can set the record ids to the real values
this.unsyncedRecords[operationId] = {
records: records,
sourceRecords: sourceRecords
}


},

read: function(operation, callback, scope) {


var me = this,
records = [],
count = this.sourceStore.getCount(),
result;

for ( var row = 0; row < count; row++ ) {
records.push( this.sourceStore.getAt( row ).copy() );
}

result = Ext.create('Ext.data.ResultSet', {
total : this.sourceStore.getTotalCount(),
count : count,
records: records,
success: true
});


Ext.apply(operation, {
resultSet: result
});


operation.setCompleted();
operation.setSuccessful();
Ext.callback(callback, scope || me, [operation]);
},


update: function(operation, callback, scope) {
var records = operation.records,
length = records.length,
rawData,
operationId = Math.floor(Math.random()*100001),
id, record, i;

for (i = 0; i < length; i++) {
record = records[i];
rawData = {};
record.fields.each(function(field) {
rawData[field.name] = record.get(field.name);
});
this.sourceStore.getById( record.getId() ).set( rawData );
record.commit();
}

operation.setCompleted();
operation.setSuccessful();
if (typeof callback == 'function') {
callback.call(scope || this, operation);
}
},

destroy: function(operation, callback, scope) {
var record, i,
records = operation.getRecords();
operation.setStarted();
for(i = 0; i < records.length; i++){
record = this.sourceStore.getById( records[i].getId() );
this.sourceStore.remove( record );
}
operation.setCompleted();
operation.setSuccessful();
},

writeOperation: function(operation, callback, scope) {
var me = this,
autoSyncValue,
options = {},
listeners = {
scope: me,
exception: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
Ext.callback(sourceListeners.exception, this.sourceStore, [batch, operation]);
},
operationcomplete: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
if( sourceListeners.operationcomplete ){
Ext.callback(sourceListeners.operationcomplete, this.sourceStore, [batch, operation]);
}
Ext.callback(callback, scope, [operation]);
},
complete: function(batch, operation){
var sourceListeners = this.sourceStore.getBatchListeners();
if( sourceListeners.complete ){
Ext.callback(sourceListeners.complete, this.sourceStore, [batch, operation]);
}
//Ext.callback(callback, scope, [operation]);
}
},
records = operation.getRecords();

operation.setStarted();
if (true){ //for now we force the sync since currenctly there is no way to get notified by the sourceStore when this operation is completed
//if (this.sourceStore.autoSync) {
//sync the data back to the server and tell both stores about the result
switch( operation.action ){
case 'create':
options.create = records;
break;
case 'update':
options.update = records;
break;
}
this.sourceStore.getProxy().batch(options, listeners);
}
}
});

Gummy
10 Nov 2011, 10:02 PM
Great, I was going to do exactly the same thing !
I'll try your code :)

basememara
3 Feb 2012, 9:14 AM
I tried getting this to work but no luck. I really hope something like this makes it into the native proxy API.

What I ended up doing was this:



//POPULATED BY CONFERENCES STORE FOR HOLDING SUBSET DATA
Ext.define('MyApp.store.Speakers', {
extend: 'Ext.data.Store',


model: 'MyApp.model.Speaker',
autoLoad: true,
proxy: {
type: 'memory',
reader: {
type: 'json'
}
},
listeners: {
beforeload: function(store, operation, options) {
var conferenceDetailsStore = Ext.getStore('ConferenceDetails');
conferenceDetailsStore.load(function(records, operation, success) {
if (success) {
store.loadData(records[0].data.Speakers);
}
});
}
}
});


I know this might be over-simplified for most, but I hope this helps someone. I turned autoLoad off for the parent store. If I am missing something, please let me know! :)

dionbeetson
5 Feb 2012, 6:03 PM
The original code (the read method) broke after we upgraded to sencha 2 beta.

To fix we simple had to call setRecords on the operations object within the read method.

Our read function now looks like:



read: function(operation, callback, scope) {


var me = this,
records = [],
count = this.sourceStore.getCount(),
result;


for ( var row = 0; row < count; row++ ) {
records.push( this.sourceStore.getAt( row ).copy() );
}


result = Ext.create('Ext.data.ResultSet', {
total : this.sourceStore.getTotalCount(),
count : count,
records: records,
success: true,
loaded: true
});


Ext.apply(operation, {
resultSet: result
});


operation.setCompleted();
operation.setSuccessful();


operation.setRecords(records);


if (typeof callback == 'function') {
callback.call(scope || this, operation);
}
},

basememara
12 Feb 2012, 9:14 PM
I am still having trouble with getting this to work. My parent store (JSONP proxy) is empty by the time the child store fires the read, which is making my child store is empty. My parent store is populated by the time the onSourceStoreProxyOperation fires though. I am not sure if I am facing a JSONP / timing issue, does this like the issue or am I missing something?



Ext.define('MyApp.store.ParentStore', {
extend: 'Ext.data.Store',


model: 'MyApp.model.Something',
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'http://somewhere.com',
extraParams: {
ProductID: 23
},
callbackKey: 'callback',
reader: {
type: 'json'
}
}
});

Ext.define('MyApp.store.ChildStore', {
extend: 'Ext.data.Store',


requires: [
'MyApp.ux.data.proxy.PagingMemoryProxy'
],


model: 'MyApp.model.ChildStore',
autoLoad: true,
proxy: {
type: 'store',
sourceStore: 'ParentStore',
reader: {
type: 'json'
}
}
});

basememara
12 Feb 2012, 9:55 PM
What's wrong with loading the parent store in the child store's initialize? I have that working, but cannot see the implications of this. The "read" event is working with empty data, but in the "initialize" all the data from the parent store is there.




Ext.define('MyApp.ux.data.proxy.StoreProxy', {
extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.store',

constructor: function(config) {
//call the parent constructor
config = config || {};
this.callParent([config]);
this.sourceStore = config.sourceStore;

if (this.sourceStore === undefined) {
Ext.Error.raise("You have to provide a parent store");
}
this.initialize();
},

initialize: function(){
//INITIALIZE SOURCE STORE
if(typeof(this.sourceStore) == 'string'){
//the store was given to us by id so let's get it from store manager
this.sourceStore = Ext.getStore(this.sourceStore);
if(this.sourceStore === undefined ) { //the parent store was not loaded, let's do that
this.sourceStore = Ext.create(this.sourceStore);
}
}


//LOAD SOURCE STORE AND FILL CURRENT STORE
this.sourceStore.load(function(sourceRecords, sourceOperation, sourceSuccess) {
Ext.getStore('Products').loadData(sourceRecords[0].data['Products']);
});
},


read: function(operation, callback, scope) {
var me = this,
records = [],
count = this.sourceStore.getCount(),
result;


for ( var row = 0; row < count; row++ ) {
records.push(this.sourceStore.getAt(row).copy());
}


result = Ext.create('Ext.data.ResultSet', {
total : this.sourceStore.getTotalCount(),
count : count,
records: records,
success: true
});


Ext.apply(operation, {
resultSet: result
});


operation.setCompleted();
operation.setSuccessful();

Ext.callback(callback, scope || me, [operation]);
}
});

martinnovak
7 Oct 2012, 8:10 AM
Hi,

I need this for a TreeStore. Has anybody ever seen such proxy synchronising two TreeStores?
M

mangeshppatil
29 Jun 2015, 5:30 AM
i am using this proxy to read data form other store to implement infinite grid so DOM will render only few number of row ..but read api getting called twice so two pages getting called initally ...but


read: function(operation, callback, scope) {




var me = this,
records = [],
count = this.sourceStore.getCount(),
result;

for ( var row = operation.start; row < (operation.start+operation.limit); row++ ) {
records.push( this.sourceStore.getAt( row ) );
}

result = Ext.create('Ext.data.ResultSet', {
total : count,
/*
this.sourceStore.getTotalCount(),
*/
count : (count>operation.limit)?operation.limit:count,
records: records,
success: true,
});




Ext.apply(operation, {
resultSet: result
});




operation.setCompleted();
operation.setSuccessful();
Ext.callback(callback, scope || me, [operation]);
},