我發現它,batch
方法Ext.data.Proxy
是創建一個Ext.data.Operation
對象發送到服務器。
我將Ext.data.proxy.Ajax
擴展爲新的batch
方法,我只是將new Ext.data.Operation
換爲我自己的操作類。
編輯
只是因爲你問DmitryB。關於爲什麼我必須實現自己的commitRecords方法的小故事是,我需要我的數據模型「internalId」字段來匹配實際的數據庫記錄ID字段。我不會進入到底爲什麼,這太令人費解了我表達,但這裏是我所做的:
怎麼我的理解,呼籲store.sync()
當commitRecords
方法燒製的最後行動之一,它會自動替換隻要您編寫服務器端控制器以在Ajax響應中返回新的服務器記錄,客戶端上的新記錄就會記錄在新的服務器端記錄中,只要同步請求執行插入或更新操作就會執行此操作。
commitRecords
的官方實現嘗試使用數據模型的「internalId」字段將此返回的服務器記錄與髒客戶端記錄進行匹配。
顯然,我不知道下一個增量數據庫ID將用於新記錄,所以我不能在客戶端將其作爲ID在數據庫與記錄同步之前分配,因此服務器記錄將永遠不會當調用commitRecords時,匹配能夠匹配髒客戶端記錄的internalId,即客戶端記錄不會獲得我需要的正確數據庫ID。
如此,因爲爲這個應用程序我寫的數據模型的所有有一個「CREATE_TIME」字段我決定把commitRecords方法使用,而不是「internalId」中的「CREATE_TIME」領域的客戶記錄匹配服務器記錄。
這裏是擴展的Ext.data。操作類,在那裏我做:
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
,現在說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...
}
});
(如果它看起來像我要對這個錯誤的方式還是錯過了一些在docs,請讓我知道,我會更樂意用內置的方法來實現此功能。)
很好找。不要害羞,並分享一些代碼:)誰知道,也許有一天它會很有用。 – dbrin
@DmitryB好的,我解釋了我自己 – Geronimo
我認爲你的用例與許多人面對的相似。根據我的經驗,如果您的模型上的ID屬性是'int'類型,那麼默認代理在運行sync()時會執行正確的操作。我曾經有我的ID屬性字符串,並導致同步失敗提交操作,如你所描述的。實質上,我的網格記錄將始終顯示「髒」標誌,即使它們已同步到服務器。 – dbrin