我找到了,batch
方法是创建Ext.data.Proxy
一个Ext.data.Operation
对象以发送到服务器。
我扩展Ext.data.proxy.Ajax
了一个新方法,我只是为我自己的 Operation 类batch
切换了。new Ext.data.Operation
编辑
只是因为你问了 DmitryB。关于为什么我必须实现自己的 commitRecords 方法的简短故事是,我需要我的数据模型“internalId”字段来匹配实际的数据库记录 ID 字段。我不会详细说明为什么,这对我来说太复杂了,无法表达,但这就是我所做的:
我的理解是,commitRecords
只要store.sync()
您编写服务器端控制器以在Ajax 响应,只要同步请求进行插入或更新,它就会执行此操作。
官方实现commitRecords
尝试通过使用数据模型的“internalId”字段将返回的服务器记录与脏客户端记录匹配。
显然,我不知道新记录的下一个增量数据库 ID 将是什么,因此我无法在记录与数据库同步之前在客户端将其分配为 ID,因此服务器记录将永远无法匹配在调用 commitRecords 时匹配脏客户端记录的 internalId,即客户端记录不会获得我需要的正确数据库 ID。
所以,因为这个应用程序的所有可写数据模型都有一个“create_time”字段,我决定让 commitRecords 方法使用“create_time”字段而不是“internalId”来匹配服务器记录和客户端记录。
这是扩展的 Ext.data.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();
}
}
}
}
},
});
正如我在答案中提到的,我发现我必须扩展代理才能使用我的新 Operation 类。我唯一扩展的是batch
方法,只替换了new Ext.data.Operation
现在所说的方法中的两行new MyApp.ux.QueryOperation
(我上面的新操作类)。当响应从服务器返回时,这将调用我自己的 commitRecords 方法。我还给扩展代理一个别名“proxy.query”,这样我就可以告诉我的商店像这样使用它:
Ext.define('MyApp.store.MyStore', {
extend: 'Ext.data.Store',
requires: [
'ST.ux.QueryProxy',
],
title: 'Student',
model: 'MyApp.model.MyModel',
proxy: {
type: 'query',
// ... ^^^^^ uses my QueryProxy now
// other configs...
}
});
(如果我似乎在使用这种错误的方式或遗漏了文档中的某些内容,请告诉我。我会更喜欢实现此功能的内置方法。)