5

Ext.data.OperationカスタムcommitRecordsメソッドを実装するために拡張しました。

このExt.data.Operationクラスは、ストアとそのプロキシ間のすべての通信に使用されます。

このcommitRecordsメソッドは、具体的には、プロキシ ライターから返されたデータに従ってデータ ストア内のデータを更新するために使用されます。

の拡張バージョンを使用するようにプロキシを設定する方法を把握できないようですExt.data.Operation

パッケージを調べてみExt.data.*ましたが、 が作成された場所が見つからないようなので、この新しい拡張クラスをカスタムメソッドでExt.data.Operation使用するためにどのクラスに指示すればよいかがわかります。Ext.data.OperationcommitRecords

他の誰かがこれを以前に拡張したことがありますか?

4

1 に答える 1

4

私はそれを見つけました、のbatchメソッドExt.data.Proxyは、Ext.data.Operationオブジェクトが作成されてサーバーに送信される場所です。

独自の Operation クラスの を切り替えるだけExt.data.proxy.Ajaxの新しいメソッドで拡張しました。batchnew 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.Operationnew 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...
    }
});

(私がこの間違った方法を行っているように思われる場合、またはドキュメントで何かを見逃しているように思われる場合は、お知らせください。この機能を実現する組み込みの方法があれば幸いです。)

于 2012-05-09T06:09:08.453 に答える