Показывая ограниченное подмножество (или отдельной записи) хранилища в Ext.DataView

В Sencha Touch мне часто нужно иметь панель Ext.DataView, содержащую небольшие записи подмножества или даже одну запись из коллекции в магазине.

Например, у меня может быть модель для Car, в которой хранятся тысячи записей автомобилей в нем app.stores.cars, но я хочу показать меньшую часть этих элементов (скажем, только спортивных автомобилей) в моем спискеOfSportsCars DataView а также показывает более полный полный набор автомобилей в моем спискеOfCars DataView.

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

Моя вторая попытка состояла в том, чтобы перезаписать метод collectData в DataView, который звучал точно так же, как и я:

var card = new Ext.DataView({
    store: app.stores.cars,
    collectData: function(records, startIndex){
        // map over the records and collect just the ones we want
        var r = [];
        for( var i=0; i<records.length; i++ )
            if( records[i].data.is_sports_car )
                r.push( this.prepareData(records[i].data, 0, records[i]) );
            return r;
    },
    tpl: new Ext.XTemplate([
            '<tpl for=".">',
                  '<div class="car">{name}</div>',
            '</tpl>'
    ]),
    itemSelector: 'div.car'
});

Полный пример можно найти здесь.

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

Как другие занимаются отображением/обновлением нескольких коллекций одних и тех же записей?

ОБНОВЛЕНИЕ Была ошибка, препятствующая работе collectData работать должным образом. С тех пор ошибка была зафиксирована в Sencha Touch 1.1.0.

Ответ 1

Как написано в комментарии:

Я использовал ваш демокод с последним выпуском Sencha Touch и открыл его с помощью Google Chrome. В текущей версии ошибка исправлена. (Версия 1.1)

Ответ 2

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

yourstore.filter('name', 'Joseph');

Также вы должны определить "root" как функцию, чтобы он всегда возвращал массив. Читатели в sencha touch asume вы всегда будете получать массив как ответ, но это не так, если у вас есть JSON с одной записью, попробуйте что-то вроде этого:

root: function(data) {
                    if (data) {
                        if (data instanceof Array) {
                            return data;
                        } else {
                            return [data];
                        }                    
                    }  

Полный код для магазина может быть таким:

YourApp.ViewName = new Ext.data.Store({
    model: 'YourApp.models.something',
    proxy: {
        type: 'scripttag',
        url: 'http://somerandomurl/service/json',
        extraParams: {
            param1: 'hello'                 
        },
        reader: {
            type: 'json',
            root: function(data) {
                    if (data) {
                        if (data instanceof Array) {
                            return data;
                        } else {
                            return [data];
                        }                    
                    }                
                }
        }
    },

});

Надеюсь, что это поможет.

Ответ 3

Я использую функции "фильтр" в Магазине. Не изменяя DataView (я использую List).

Вот фрагмент, в котором я буду выделять Программы с категорией, которая соответствует регулярному выражению. (У меня есть программы с полем).

MyApp.stores.Programs.filter(function(object) {
    var regex = new RegExp(filterValue, 'i');
    return object.data.category.search(regex) >= 0; // found match
  });

Вы можете очистить фильтр следующим образом:

MyApp.stores.Programs.clearFilter(false);

Это немедленно обновит DataView (я использую List) (это потрясающе).

Таким образом, в вашем фильтре вы можете просто отфильтровать спортивные автомобили или автомобили определенной цены или что-то еще.

Надеюсь, что это поможет...

Ответ 4

Для моего понимания Sencha Touch это не лучший подход. Если он может быть хорош для производительности, вы используете второй "ведомый" магазин с встроенными данными (http://docs.sencha.com/touch/1-1/#!/api/Ext.data.Store), которые вы можете автоматически заполнить из основного хранилища подмножество информации, которую хотите показать, когда событие происходит в главном хранилище, т.е. событие загрузки.

Если вы хотите иметь дело только с одним магазином, я могу представить, как использовать xtemplate с тегом tpl if в каталоге данных, где вы хотите показать только некоторую информацию http://docs.sencha.com/touch/1-1/#!/api/Ext. писать пустые записи. Возможно, также лучшим решением может быть использование пользовательской функции фильтрации внутри xtemplate, чтобы поместить css с видимостью в скрытые элементы, которые вы не хотите видеть.