ExtJS 4.2: несколько вставок

Итак, скажем, у меня есть серверная часть магазина, поэтому мы делаем все удаленно. Пример магазинов:

   Ext.create('Ext.data.Store', {
        model: 'MyApp.model.ContactModel',
        remoteFilter: true, 
        remoteSort: true,
        autoLoad: true,
        autoSync: true,
        storeId: 'ContactStore-1'
    });
   Ext.create('Ext.data.Store', {
        model: 'MyApp.model.ContactModel',
        remoteFilter: true, 
        remoteSort: true,
        autoLoad: true,
        autoSync: true,
        storeId: 'ContactStore-2'
    });

У меня возникла проблема, когда я делаю следующее:

Ext.getStore('ContactStore-1').insert(0,{'name':'say'});
Ext.getStore('ContactStore-2').insert(0,{'name':'hi'});

Что происходит, так это то, что когда я смотрю на БД, у меня появляется 2 записи. Я получаю «привет» один раз и «говорю» дважды. Судя по всему, происходит то, что отправляется первый оператор вставки, а затем отправляется второй оператор вставки, но с данными из обеих вставок (я предполагаю, что они используют одну и ту же модель и, следовательно, один и тот же прокси)

Мысли о том, как я могу решить эту проблему, чтобы запросы на вставку не объединялись автоматически?

Модель для вашего удовольствия:

Ext.define('MyApp.model.ContactModel', {
extend: 'Ext.data.Model',

idProperty: 'idContact',

fields: [
    {
        name: 'idContact',
        type: 'int'
    },
    {
        name: 'name',
        type: 'string'
    }
],

proxy: {
    type: 'direct',
    api: {
        create: contact.createRecord,
        read: contact.getResults,
        update: contact.updateRecords,
        destroy: contact.destroyRecord
},
    reader: {
        type: 'json',
        root: 'data'
    }
}
});

person Aram Papazian    schedule 27.06.2013    source источник
comment
Что будет, если перенести прокси в магазин?   -  person existdissolve    schedule 28.06.2013
comment
Как изменение прокси для магазина изменит ситуацию? Из того, что я вижу в почтовых звонках, даже когда звонят две разные модели, они иногда группируются в 1 массовый звонок.   -  person Aram Papazian    schedule 28.06.2013
comment
Боковое примечание: я попробовал, и это не сработало = / Как я и предполагал, он все еще упаковывает все вызовы вместе.   -  person Aram Papazian    schedule 28.06.2013


Ответы (1)


Я думаю, что вы не возвращаете правильные данные со стороны сервера при создании. Если вы не вернете идентификатор, созданный сервером при первой вставке, ExtJS все равно будет думать, что ваш элемент «говорит» является phantom. То есть он еще не был сохранен на стороне сервера.

Когда вы сделаете вторую вставку, магазин выполнит синхронизацию, поскольку у вас включена автосинхронизация. Синхронизация отправит ВСЕ ожидающие изменения. Поскольку ваш элемент «привет» новый, он будет отправлен в POST, как и ожидалось. Но поскольку ваш предыдущий элемент «привет» не имеет идентификатора, сгенерированного сервером, и все еще является фантомом, он также будет отправлен в POST с вашей второй синхронизацией (запущенной вставкой).

По сути, сервер должен вернуть новый идентификатор с набором результатов успеха, чтобы ExtJS знал, что элемент был сохранен сервером. Вот пример из моего REST API:

Запрос имеет эту полезную нагрузку (проверьте вкладку сети инструментов разработчика Chrome).

POST to http://localhost:8081/api/channel?_dc=1372594759864

{"id":0,"number":0,"name":"test"}

Это ответ сервера (200 OK):

{
  "result": {
    "id": 4, // <- important
    "number": 3,
    "name": "test",
  },
  "success": true,
  "location": "http://localhost:8081/api/item/4",
  "userMessage": null,
  "userTitle": "Success",
  "devErrors": null
}

Все поля в модели обновляются данными в ответе сервера, и, таким образом, ваши приветственные элементы получат свой набор идентификаторов сервера. Когда идентификатор установлен, для свойства фантома устанавливается значение false. Вы можете посмотреть исходный код в js-файле Ext.data.Model, если хотите копнуть глубже. :)

В вашем случае вы должны иметь idContact в возвращаемом объекте, так как это ваше idProperty.

Если вы хотите приостановить автоматическую синхронизацию, выполните вставку и синхронизацию вручную, а затем снова включите автоматическую синхронизацию, вы можете использовать SuspendAutoSync и ResumeAutoSync.

На мой взгляд, лучший способ добавить модели в магазины — это создать свою модель, сохранить ее и в случае успеха поместить в магазин. Это требует, чтобы у вас был прокси в каждой модели. Это будет выглядеть примерно так:

var hi = Ext.create('MyApp.model.ContactModel', {
    name: 'hi'
});

hi.save({
    success: function (record, operation) {
        Ext.getStore('ContactStore-1').add(hi);
        // You could do your second insert here that is dependent on the first to be completed
    },
    failure: function (record, operation) {
        Ext.MessageBox.alert("Error", "Could not save model at this time...");
    },
    scope: this
});

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

person oldwizard    schedule 30.06.2013
comment
Я думаю, что это может помочь мне создать обходной путь, но проблема в том, что я отправляю вставки одну за другой, поэтому у меня нет возможности «ждать», чтобы убедиться, что данные были выполнены. Есть ли способ отключить автосинхронизацию на мгновение, чтобы «сохранить» все вставки, а затем синхронизировать все сразу? - person Aram Papazian; 01.07.2013
comment
Я думаю, я также, возможно, не понимаю это должным образом. Когда я смотрю на сообщения, обе вставки происходят всего за 1 вызов (то есть один запрос на публикацию), но в запросе на публикацию есть 2 запроса. В первом есть только «говорить», а во втором есть и «говорить», и «привет». Это я думаю, что это странно. Если он делает один вызов, а затем делает второй вызов с обоими из-за того, что первый является фантомным, это имело бы смысл, но он делает это за 1 вызов... - person Aram Papazian; 01.07.2013
comment
Как выглядит ответ вашего сервера на звонки? Скопируйте и вставьте ответ с вкладки ответов в свой вопрос. - person oldwizard; 02.07.2013
comment
Итак, в итоге я создал магазин без автосинхронизации, а затем синхронизировал его вручную. Спасибо за помощь =) - person Aram Papazian; 03.07.2013