Заставить прокси использовать расширенный Ext.data.Operation

Я расширил Ext.data.Operation для реализации пользовательского метода commitRecords.

Класс Ext.data.Operation используется для связи между магазинами и их прокси.

Метод commitRecords специально используется для обновления данных в хранилище данных в соответствии с данными, возвращенными от модуля записи прокси.

Я не могу понять, как настроить мои прокси для использования моей расширенной версии Ext.data.Operation.

Я просматривал пакет Ext.data.*, но не могу найти, где создается Ext.data.Operation, поэтому я буду знать, какой класс использовать для использования этого нового расширенного класса Ext.data.Operation с пользовательским методом commitRecords.

Кто-нибудь еще расширил это раньше, может дать мне несколько советов?


person egerardus    schedule 09.05.2012    source источник


Ответы (1)


Я нашел это, метод batch Ext.data.Proxy - это то, где объект Ext.data.Operation создается для отправки на сервер.

Я расширил Ext.data.proxy.Ajax новым методом batch, в котором я просто отключил new Ext.data.Operation для своего собственного класса Operation.

ИЗМЕНИТЬ

Только потому, что вы спросили DmitryB. Короткая история о том, почему мне пришлось реализовать свой собственный метод commitRecords, заключается в том, что мне нужно, чтобы поля «internalId» моих моделей данных соответствовали фактическому полю идентификатора записи базы данных. Я не буду вдаваться в подробности, почему именно, это слишком запутанно для меня, чтобы выразить, но вот что я сделал:

Насколько я понимаю, метод commitRecords запускается как одно из последних действий при вызове store.sync(), он автоматически заменяет грязные записи на стороне клиента новыми записями на стороне сервера, пока вы пишете свой серверный контроллер для возврата новой записи сервера в ответе Ajax он делает это всякий раз, когда запрос синхронизации выполняет вставку или обновление.

Официальная реализация commitRecords пытается сопоставить эту возвращенную запись сервера с грязной записью клиента, используя поле «internalId» модели данных.

Очевидно, я понятия не имею, каким будет идентификатор следующей инкрементной базы данных для новых записей, поэтому я не могу назначить его на стороне клиента в качестве идентификатора до того, как запись синхронизируется с базой данных, поэтому запись сервера никогда не будет соответствовать. сопоставляться с внутренним идентификатором грязной записи клиента при вызове commitRecords, т. е. запись клиента не получит правильный идентификатор базы данных, который мне нужен.

Итак, поскольку все мои записываемые модели данных для этого приложения имеют поле «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();
                    }
                }
            }
        }
    },

});

Как я уже упоминал в ответе, я обнаружил, что мне пришлось расширить прокси, чтобы использовать мой новый класс операций. Единственное, что я расширил, это метод batch, заменив только две строки в методе, в котором говорилось new Ext.data.Operation, теперь говорят new MyApp.ux.QueryOperation (мой новый класс Operation выше). Затем он вызвал мой собственный метод 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...
    }
});

(Если кажется, что я иду по этому пути неправильно или что-то упустил в документации, сообщите мне об этом. Я был бы счастливее, если бы встроенный метод достижения этой функциональности.)

person egerardus    schedule 09.05.2012
comment
хорошая находка. не стесняйтесь и поделитесь кодом :) кто знает, может когда-нибудь он пригодится. - person dbrin; 10.05.2012
comment
@DmitryB Хорошо, я объяснился - person egerardus; 11.05.2012
comment
Я думаю, что ваш вариант использования похож на то, с чем сталкиваются многие. По моему опыту, если ваш атрибут ID в вашей модели имеет тип «int», прокси-сервер по умолчанию делает все правильно при запуске sync(). Раньше у меня было свойство ID в виде строки, и это приводило к сбою операции фиксации синхронизации, как вы описали. По сути, в моих записях сетки всегда будут отображаться «грязные» флаги, даже если они были синхронизированы с сервером. - person dbrin; 11.05.2012