私はそれを見つけました、のbatch
メソッドExt.data.Proxy
は、Ext.data.Operation
オブジェクトが作成されてサーバーに送信される場所です。
独自の Operation クラスの を切り替えるだけExt.data.proxy.Ajax
の新しいメソッドで拡張しました。batch
new Ext.data.Operation
編集
あなたがDmitryBに尋ねたからです。独自の commitRecords メソッドを実装する必要があった理由について簡単に説明すると、データ モデルの「internalId」フィールドを実際のデータベース レコード ID フィールドと一致させる必要があったからです。正確な理由については説明しませんが、複雑すぎて表現できませんが、私が行ったことは次のとおりです。
私が理解しているように、commitRecords
メソッドはstore.sync()
、サーバー側コントローラーを記述して新しいサーバー レコードをAjax 応答。同期要求が挿入または更新を行うたびにこれを行います。
の公式実装はcommitRecords
、データ モデルの「internalId」フィールドを使用して、この返されたサーバー レコードをダーティ クライアント レコードと照合しようとします。
明らかに、新しいレコードの次の増分データベース ID がどうなるかわからないため、レコードがデータベースと同期する前にクライアント側でそれを ID として割り当てることができないため、サーバー レコードが一致することはありません。 commitRecords が呼び出されたときに、ダーティ クライアント レコードの internalId と照合します。つまり、クライアント レコードは、必要な正しいデータベース ID を取得しません。
このアプリのすべての書き込み可能なデータ モデルには「create_time」フィールドがあるため、「internalId」の代わりに「create_time」フィールドを使用して、commitRecords メソッドがサーバー レコードとクライアント レコードを一致させることにしました。
拡張された 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
たメソッドの 2 行だけを置き換えました(上記の新しい Operation クラス)。これにより、サーバーから応答が返ってきたときに、独自の commitRecords メソッドが呼び出されました。また、拡張プロキシにエイリアス「proxy.query」を付けて、ストアに次のように使用するように指示できるようにしました。new Ext.data.Operation
new MyApp.ux.QueryOperation
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...
}
});
(私がこの間違った方法を行っているように思われる場合、またはドキュメントで何かを見逃しているように思われる場合は、お知らせください。この機能を実現する組み込みの方法があれば幸いです。)