我已将Ext.data.Operation
扩展为实施自定义commitRecords
方法。
Ext.data.Operation
类用于商店及其代理之间的所有通信。
commitRecords
方法专门用于根据代理编写器返回的数据更新数据存储中的数据。
我似乎无法掌握如何设置我的代理以使用Ext.data.Operation
的扩展版本。
我一直在搜索Ext.data.*
包,但似乎无法找到创建Ext.data.Operation
的位置,因此我将知道使用这个新的扩展Ext.data.Operation
要告诉哪个类使用自定义commitRecords
方法的类。
有没有其他人延长过这个,可以给我一些指示?
答案 0 :(得分:4)
我发现它,batch
的{{1}}方法是创建Ext.data.Proxy
对象以发送到服务器的地方。
我使用新的Ext.data.Operation
方法扩展Ext.data.proxy.Ajax
,我只为我自己的操作类切换batch
。
修改强>
只因为你问过DmitryB。关于为什么我必须实现自己的commitRecords方法的简短故事是我需要我的数据模型“internalId”字段来匹配实际的数据库记录ID字段。我不会详细说明为什么,这对我来说太复杂了,但这就是我所做的:
我是如何理解的,new Ext.data.Operation
方法作为调用commitRecords
时的最后一个操作之一被触发,它会自动用新的服务器端记录替换客户端的脏记录,只要你编写服务器端控制器以返回Ajax响应中的新服务器记录,只要同步请求执行插入或更新,它就会执行此操作。
store.sync()
的官方实现尝试使用数据模型的“internalId”字段将此返回的服务器记录与脏客户端记录进行匹配。
显然,我不知道新记录的下一个增量数据库ID是什么,因此在记录与数据库同步之前,我无法在客户端将其分配为ID,因此服务器记录永远不会匹配能够在调用commitRecords时匹配脏客户端记录的internalId,即客户端记录将无法获得我需要的正确数据库ID。
因此,因为此应用程序的所有我的可写数据模型都有一个“create_time”字段,所以我决定让commitRecords方法使用“create_time”字段将服务器记录与客户端记录相匹配“internalId”。
这是扩展的Ext.data.Operation类,我这样做了:
commitRecords
正如我在答案中提到的,我发现我必须扩展代理才能使用我的新Operation类。我扩展的唯一内容是Ext.define('MyApp.ux.QueryOperation', {
extend: 'Ext.data.Operation',
/**
* Use the date_created timestamp if we cant match to an ID.
* This allows client records that did not previously exist on the server
* to be updated with the correct server ID and data
* NB: All implementing data models require a "date_created" field.
*/
commitRecords: function (serverRecords) {
var me = this,
mc, index, clientRecords, serverRec, clientRec;
if (!me.actionSkipSyncRe.test(me.action)) {
clientRecords = me.records;
if (clientRecords && clientRecords.length) {
if (clientRecords.length > 1) {
mc = new Ext.util.MixedCollection();
mc.addAll(serverRecords);
Ext.each(clientRecords, function(clientRec) {
serverRec = mc.findBy(function(record) {
var clientId = clientRec.getId(),
clientTime = clientRec.get('date_created').getTime(),
serverTime = record.get('date_created').getTime();
if(clientId && record.getId() === clientId) {
return true;
}
// timestamp can be within 2ms of record
// (it seems to change slightly in serialization)
return (clientTime > serverTime - 2 && clientTime < serverTime + 2);
});
me.updateClientRecord(clientRec, serverRec);
});
} else {
clientRec = clientRecords[0];
serverRec = serverRecords[0];
me.updateClientRecord(clientRec, serverRec);
}
if (me.actionCommitRecordsRe.test(me.action)) {
for (index = clientRecords.length; index--; ) {
clientRecords[index].commit();
}
}
}
}
},
});
方法,只替换方法中的两行,表示batch
现在说new Ext.data.Operation
(我上面的新操作类)。然后,当从服务器返回响应时,这会调用我自己的commitRecords方法。我还给扩展代理一个别名“proxy.query”,以便我可以告诉我的商店使用它:
new MyApp.ux.QueryOperation
(如果看起来我正在采用这种错误方式或错过了文档中的内容,请告诉我。我会更乐意使用内置方法来实现此功能。)