ExtJS 4:克隆存储
Posted
技术标签:
【中文标题】ExtJS 4:克隆存储【英文标题】:ExtJS 4: cloning stores 【发布时间】:2012-09-19 04:22:50 【问题描述】:我正在尝试弄清楚如何在不保留旧参考的情况下克隆 Ext.data.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
]
);
下面是我想做的一个例子:
var target = source;
target.removeAll ();
// Here I need to have target empty and source unchanged
// But in this case, source is empty as well
现在,在上面的示例中,复制是通过引用完成的,而我需要通过值来完成。
所以我在文档中找到了Ext.clone ()
,但它似乎不适用于复杂的对象,比如Ext.data.Store
:
var target = Ext.clone (source);
target.removeAll ();
// source is still empty
然后我尝试使用Ext.data.Model.copy ()
,但唯一可行的方法是:
var target = Ext.create ('Ext.data.Store',
fields: ['name', 'age']
);
source.each (function (model)
target.add (model.copy ());
);
现在,出于我的原因,我不想实例化另一个Ext.data.Store
,所以我想避免这种情况:
var target = Ext.create ('Ext.data.Store',
fields: ['name', 'age']
);
我想要这样的东西:
var target;
source.each (function (model)
target.add (model.copy ());
);
但是,显然,它不起作用。
那么,如何克隆源存储?
【问题讨论】:
我认为没有办法复制商店。实例化一个新的空的可能是您唯一的选择。 您介意解释一下为什么要克隆您的商店吗? 因为我需要将一些数据表示到网格中。我正在为复杂的嵌套 XML 数据库使用 MVC 和复杂的模型关联。我正在寻找与定义新商店不同的东西,如果可能的话。 【参考方案1】:ExtJS 3.x 解决方案
试试这个:
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;
注意:Ext.ux.clone
是一个单独的插件(你会找到它),它可以对对象进行 deep 克隆。也许,Ext JS 4 提供了一个熟悉的东西,我不知道.. 我从 Ext JS 3.x 开始使用这个特殊的克隆
创建新商店时可能需要指定代理memory
(我现在不确定,因为我一直使用“提供”的方式。
ExtJS 4.x 解决方案
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;
【讨论】:
正如 Yoshi 所说,也许这是唯一的方法。所以,这正是我想要的!我在您的答案中添加了 ExtJS4 解决方案!非常感谢! 这些方法不会依次复制记录可能具有的任何关系(存储),因此对于具有关系的模型来说不够深。 嗯,这意味着关系数据没有存储到data
。更“深”是不可能的。 ;)
ExtJS 4 解决方案不会像 pcguru 所说的那样复制任何关系!
只需使用 target.add(record.copy()) 您不需要该行上方的额外代码。【参考方案2】:
ExtJS 6.x、5.x 和 4.x 解决方案
这是一个准所有 ExtJS 版本的解决方案。请注意,record.copy 已经创建了数据的克隆。无需再次 Ext.clone 。
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;
【讨论】:
我会试试看效果如何 这样更整洁。如果您将“source.getModel()”更改为“source.model”,则在 ExtJS4 中可以正常工作。我还在开头添加了这一行,以提供提供商店 ID 的选项: source = Ext.isString(source) ? Ext.data.StoreManager.lookup(source) : source; 对于 Ext 6.5 和 7,我会使用 record.clone() 而不是 record.copy()。像dropped
、phantom
和dirty
这样的状态会被保留。【参考方案3】:
我在 Ext.js 4.1 中成功完成了以下操作:
var source = Ext.create('Ext.data.Store',
fields: ['name', 'age'],
data: [
name: 'foo', age: 20,
name: 'boo', age: 30,
],
);
在方法中:
cloneStore: function (source)
var clone = Ext.create('Ext.data.Store',
fields: ['name', 'age']
);
// load source store data
clone.loadData(source.data.items);
return clone;
内联:
var clone = Ext.create('Ext.data.Store',
fields: ['name', 'age']
).loadData(source.data.items);
【讨论】:
【参考方案4】:因为这仍然是我一直在寻找的东西,而上面的答案并没有为我解决问题,所以我自己找到了另一个解决方案:
var target = Ext.create ('Ext.data.Store',
// add other properties here if needed
reader: source.reader
)
这对我创建商店的克隆很有用。
【讨论】:
以上是关于ExtJS 4:克隆存储的主要内容,如果未能解决你的问题,请参考以下文章