ExtJS 4: cloning stores

Wilk picture Wilk · Sep 27, 2012 · Viewed 23.5k times · Source

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?

Answer

Christiaan Westerbeek picture Christiaan Westerbeek · Nov 4, 2015

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;
}