Reputation: 8113
I'm trying to figure out how to clone an Ext.data.Store
without keeping the old reference.
Let me explain better with some code. Here's the source store:
var source = Ext.create ('Ext.data.Store', {
fields: ['name', 'age'] ,
data: [
{name: 'foo', age: 20} ,
{name: 'boo', age: 30} ,
{name: 'too', age: 10} ,
{name: 'yoo', age: 80} ,
{name: 'zoo', age: 30}
]
});
Follows an example of what I want to do:
var target = source;
target.removeAll ();
// Here I need to have target empty and source unchanged
// But in this case, source is empty as well
Now, in the above example the copy is done by reference while I need to do it by value.
So I found Ext.clone ()
in the docs but it seems it doesn't work for complex object, like Ext.data.Store
:
var target = Ext.clone (source);
target.removeAll ();
// source is still empty
Then I tried with Ext.data.Model.copy ()
but the only way to do it work is this:
var target = Ext.create ('Ext.data.Store', {
fields: ['name', 'age']
});
source.each (function (model) {
target.add (model.copy ());
});
Now, for my reasons, I don't want to instantiate another Ext.data.Store
, so I want to avoid this:
var target = Ext.create ('Ext.data.Store', {
fields: ['name', 'age']
});
I'd like to have something like this:
var target;
source.each (function (model) {
target.add (model.copy ());
});
But, obviously, it doesn't work.
So, how can I clone the source store?
Upvotes: 14
Views: 26999
Reputation: 1179
since this is still something I was looking for and the above answers did not fix it for me, I found another solution myself:
var target = Ext.create ('Ext.data.Store', {
// add other properties here if needed
reader: source.reader
})
This worked for me to create clones of a store.
Upvotes: 0
Reputation: 1214
I did the following successfully in Ext.js 4.1:
var source = Ext.create('Ext.data.Store', {
fields: ['name', 'age'],
data: [
{name: 'foo', age: 20},
{name: 'boo', age: 30},
],
});
In a method:
cloneStore: function (source) {
var clone = Ext.create('Ext.data.Store', {
fields: ['name', 'age']
});
// load source store data
clone.loadData(source.data.items);
return clone;
}
Inline:
var clone = Ext.create('Ext.data.Store', {
fields: ['name', 'age']
}).loadData(source.data.items);
Upvotes: 2
Reputation: 11137
ExtJS 6.x, 5.x and 4.x solution
Here's a quasi-all ExtJS versions solution. Mind you that record.copy already creates a clone of the data. No need to Ext.clone that again.
function deepCloneStore (source) {
source = Ext.isString(source) ? Ext.data.StoreManager.lookup(source) : source;
var target = Ext.create(source.$className, {
model: source.model,
});
target.add(Ext.Array.map(source.getRange(), function (record) {
return record.copy();
}));
return target;
}
Upvotes: 15
Reputation: 1993
ExtJS 3.x solution
Try this:
cloneStore : function(originStore, newStore) {
if (!newStore) {
newStore = Ext.create('Ext.data.Store', {
model : originStore.model
});
} else {
newStore.removeAll(true);
}
var records = [], originRecords = originStore.getRange(), i, newRecordData;
for (i = 0; i < originRecords.length; i++) {
newRecordData = Ext.ux.clone(originRecords[i].copy().data);
newStore.add(new newStore.model(newRecordData, newRecordData.id));
}
newStore.fireEvent('load', newStore);
return newStore;
}
Note: Ext.ux.clone
is a separated plugin (you will find it) which makes a deep clone of an object. Maybe, Ext JS 4 provides a familiar thing, I don't know.. I'm using this special clone since Ext JS 3.x
It is possible that it is required to specify the proxy memory
when creating a new store (I'm not sure right now because I'm using always the "provided" way.
ExtJS 4.x solution
function deepCloneStore (source) {
var target = Ext.create ('Ext.data.Store', {
model: source.model
});
Ext.each (source.getRange (), function (record) {
var newRecordData = Ext.clone (record.copy().data);
var model = new source.model (newRecordData, newRecordData.id);
target.add (model);
});
return target;
}
Upvotes: 13