ExtJS — удаленная фильтрация вызывает проблемы

а) Вот скрипт JS, чтобы показать, что происходит: http://jsfiddle.net/CKpPW/ б) Чтобы воспроизвести проблему, выберите первый раскрывающийся список и обратите внимание на то, как отображается полное имя. Затем разверните второй раскрывающийся список и обратите внимание, как исчезает отображение первого раскрывающегося списка.

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

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

Вот слушатель, который должен произойти при расширении, так как мне нужна возможность фильтровать каждое поле со списком по-разному:

 listeners: {
     expand: {
         fn: function(){
             names.clearFilter(true);
            names.filter('id', 1);                
        }
    }
},

person Aram Papazian    schedule 20.06.2013    source источник


Ответы (1)


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

component <=> store <=> proxy <=> actual data

Поэтому, если вы хотите поделиться данными, вам нужно поделиться прокси, а не хранилищем.

Вот, например, как исправить скрипку:

var proxy = Ext.create('Ext.data.proxy.Memory', {
    reader: 'json',
    data : [
        {'id':0,"FirstName":"Frédéric", "LastName":"Bastiat"},
        {'id':1,"FirstName":"John", "LastName":"Alcatraz"},
        {'id':2,"FirstName":"Nasha", "LastName":"Cartoga"}
        //...
    ]    
});

var store1 = Ext.create('Ext.data.Store', {
    proxy: proxy,
    fields: ['id','FirstName', 'LastName'],
    remoteFilter:true,
    remoteSort:true,
    filters: [{property: 'id', value: 1}]
});

var store2 = Ext.create('Ext.data.Store', {
    proxy: proxy,
    fields: ['id','FirstName', 'LastName'],
    remoteFilter:true,
    remoteSort:true,
    filters: [{property: 'id', value: 2}]
});

// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
    fieldLabel: 'Choose Name',
    store: store1,
    id: 'nameCombo',
    queryMode: 'local',
    displayField: 'FirstName',
    valueField: 'FirstName',
    displayTpl: Ext.create('Ext.XTemplate',
        '<tpl for=".">',
        '<tpl if="FirstName">',
        '{FirstName}',
        '</tpl>',
        ' ',
        '<tpl if="LastName">',
        '{LastName}',
        '</tpl>',
        '</tpl>'),
    renderTo: Ext.getBody()
});

// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
    fieldLabel: 'Choose Name',
    id: 'nameCombo2',
    queryMode: 'local',
    displayField: 'FirstName',
    valueField: 'FirstName',
    store: store2,
    displayTpl: Ext.create('Ext.XTemplate',
        '<tpl for=".">',
        '<tpl if="FirstName">',
        '{FirstName}',
        '</tpl>',
        ' ',
        '<tpl if="LastName">',
        '{LastName}',
        '</tpl>',
        '</tpl>'),
    renderTo: Ext.getBody()
});

Теперь ваш следующий вопрос, вероятно, будет о том, как передать ваши данные на стороне сервера в этот прокси-сервер памяти на стороне клиента... К сожалению, фреймворк не предлагает готового решения.

Самый простой способ, вероятно, — загрузить ваши данные один раз с помощью обычного запроса AJAX, поместить их в прокси-сервер памяти и передать этот прокси-сервер всем вашим магазинам.

Или вы можете проявить творческий подход и попробовать реализовать свой собственный прокси, который сочетает загрузку с сервера и кэширование на клиенте. Этого довольно просто добиться, переопределив прокси-сервер памяти, но достаточно скоро вы столкнетесь с кучей сложных вопросов... Как обрабатывать кэширование для операций с разными параметрами? Как вообще обрабатывать параметры запроса? А как насчет других операций CRUD, помимо чтения? И т. д. Если вы все равно хотите попробовать, вы можете посмотреть эту расширение для вдохновения (оно написано для Touch, поэтому вы не можете использовать его напрямую, но принципы те же, что и для ExtJS).

person rixo    schedule 20.06.2013
comment
Технически я не указал все данные, которые у меня были выше, но у меня уже есть настройка прокси, но она настроена на модели. Разве наличие прокси на модели не сделало бы примерно то же самое? Или есть какой-то параметр, который мне нужно установить, чтобы он использовал прокси-сервер каждый раз, когда создается поле со списком? - person Aram Papazian; 21.06.2013
comment
Вы хотите, чтобы ваш прокси-сервер был общим, поэтому хорошо настроить его в модели. Чего вы хотите избежать, так это совместного использования экземпляра магазина, как вы делаете в своей скрипке. Возможно, в моем примере кода не было ясно, что будут созданы 2 разных хранилища, я отредактировал его, чтобы сделать это очевидным. - person rixo; 21.06.2013
comment
Значит, тогда мне придется создавать новый магазин для каждого поля со списком? Нет ли динамического способа сделать это так, чтобы все поля со списком получали новое хранилище, а не текущее глобальное хранилище? Я собираюсь возиться с параметром «магазин» в поле со списком, но не уверен, что это сильно поможет. - person Aram Papazian; 21.06.2013
comment
Боковое примечание: я использую Architect, что иногда немного сбивает с толку, когда все работает так, как вы хотите. - person Aram Papazian; 21.06.2013
comment
Да, опция конфигурации магазина сделает это. Если вы установите там объект конфигурации (а не экземпляр хранилища!), то Ext создаст новое хранилище с этой конфигурацией для каждой комбинации. Фактически, это то, что делала предыдущая версия моего кода (вы все еще можете просмотреть отредактированную версию, щелкнув ссылку отредактировано...). - person rixo; 21.06.2013
comment
Ну, проблема в том, что Architect разрешает использовать строки только для раздела «магазин» =/ Есть ли дополнительный метод? Или создание нового магазина будет единственным вариантом? - person Aram Papazian; 21.06.2013
comment
Действительно? Это неожиданное решение разработчиков Architect... Возможно, вы сможете переопределить метод initComponent комбо и создать там магазин. - person rixo; 21.06.2013
comment
Это было странно. Вы можете либо изменить его на хранилище, либо на массив, оба из которых преобразуются в строку. Я никогда не переопределял initComponent. Можете ли вы рассказать мне, как я это сделаю (или где я могу найти хороший учебник)? [Примечание: следующие 2 дня меня не будет, поэтому я не смогу ответить пару дней. В понедельник попробую этот метод. Спасибо за вашу помощь до сих пор =)] - person Aram Papazian; 21.06.2013
comment
В этом ответе есть примеры как переопределения или расширения компонента, так и его initComponent метода. Принципы те же, что и для комбо. - person rixo; 21.06.2013
comment
У меня было несколько разных попыток, но я заставил его работать правильно. Спасибо =) - person Aram Papazian; 25.06.2013