Vitaly
Vitaly

Reputation: 4498

Sencha: Two lists showing different content from the same store. Possible?

Say, we have this in the store:

[
    {
        name: 'Criteria 1',
        status: 'In'
    },
    {
        name: 'Criteria 2',
        status: 'Out'
    },
    ...
]

We need to display criteria that are In in one list and those that are Out in another from that store. Is it possible to do?

View structure

Upvotes: 2

Views: 1799

Answers (4)

Stevko
Stevko

Reputation: 4495

extjs 5 added chained stores for this very scenario

http://dev.sencha.com/ext/5.0.0/examples/kitchensink/#binding-chained-stores

Ext.define('KitchenSink.view.binding.ChainedStoresModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.binding.chainedstores',

stores: {
    everyone: {
        model: 'Person',
        data: KitchenSink.model.Person.generateData(15, 10)
    },
    adults: {
        source: '{everyone}',
        filters: [{
            property: 'age',
            value: 18,
            operator: '>='
        }],
        sorters: [{
            property: 'age',
            direction: 'ASC'
        }]
    }
}
});

Upvotes: 2

Yvo
Yvo

Reputation: 19263

A few months ago I've created a FilteredStore class for Sencha.

It's not perfect, but might be very usefull to you.
It basically allows you to create a new store by filtering another one.

Ext.define('Ext.data.FilteredStore', {
    extend: 'Ext.data.Store',

    ///////////////////////////////////////////////////////////////////////////
    // Configuration

    config: {
        model: 'Ext.data.Model',
        sourceStore: undefined,
        filter: undefined
    },

    ///////////////////////////////////////////////////////////////////////////
    // Fields
    sourceStore: undefined,

    ///////////////////////////////////////////////////////////////////////////
    // Configuration methods

    updateSourceStore: function (newValue, oldValue) {
        //TODO: Remove hooks from old store (oldValue)

        // See if we've received a valid source store
        if (!newValue)
            return;

        // Resolve the source store
        this.sourceStore = Ext.data.StoreManager.lookup(newValue);
        if (!this.sourceStore || !Ext.isObject(this.sourceStore) || !this.sourceStore.isStore)
            Ext.Error.raise({ msg: 'An invalid source store (' + newValue + ') was provided for ' + this.self.getName() });

        // Listen to source store events and copy model
        this.setModel(this.sourceStore.getModel());
        this.sourceStore.on({
            addrecords: 'sourceStoreAdded',
            removerecords: 'sourceStoreRemoved',
            refresh: 'sourceStoreChanged',
            scope: this
        });

        // Load the current data
        this.sourceStoreChanged();
    },
    updateFilter: function () {
        // Load the current data
        this.sourceStoreChanged();
    },

    ///////////////////////////////////////////////////////////////////////////
    // Store overrides

    fireEvent: function (eventName, me, record) {
        // Intercept update events, remove rather than update if record is no longer valid
        var filter = this.getFilter();
        if (filter && eventName === 'updaterecord' && !filter(record))
            this.remove(record);
        else
            this.callParent(arguments);
    },

    ///////////////////////////////////////////////////////////////////////////
    // Event handlers

    sourceStoreAdded: function (sourceStore, records) {
        var filter = this.getFilter();
        if (!filter)
            return;

        // Determine which records belong in this store
        var i = 0, len = records.length, record, newRecords = [];
        for (; i < len; i++) {
            record = records[i];

            // Don't add records already in the store
            if (this.indexOf(record) != -1)
                continue;

            if (filter(record))
                newRecords.push(record);
        }

        // Add the new records
        if (newRecords.length)
            this.add(newRecords);
    },
    sourceStoreRemoved: function (sourceStore, records) {
        this.remove(records);
    },
    sourceStoreChanged: function () {
        // Clear the store
        this.removeAll();

        var records = [],
            i, all, record,
            filter = this.getFilter();

        // No filter? No data
        if (!filter)
            return;

        // Collect and filter the current records
        all = this.sourceStore.getAll();
        for (i = 0; i < all.length; i++) {
            record = all[i];
            if (filter(record))
                records.push(record);
        }

        // Add the records to the store
        this.add(records);
    }
});

Example usage code:

Ext.define('My.store.ActiveItems', {
    extend: 'Ext.data.FilteredStore',
    config: {
        sourceStore: 'Items',
        filter: function (record) { return record.get('IsActive'); }
    }
});

Upvotes: 4

Patrick Chu
Patrick Chu

Reputation: 1603

This is not possible. When you tie a list to a store, it reflects all the changes made to that store. They are always in sync. When you put a filter on a store, the items[] array of that store is changed, and that will change any list that is attached to that store.

(Similarly, if you tie a chart to a store, the chart is automatically updated as the store is updated.)

You could have two stores that are initially filled (and maintained) with the same data, and then apply different filters to the two stores.

Upvotes: 1

Vikal Sharma
Vikal Sharma

Reputation: 555

Try applying filter to the store. May be this will work.

    var newstore=Ext.getStore("Store"); // If you have Store.js
    newstore.clearFilter();//clear previous filter
    newstore.filter('status', 'In'); 

Upvotes: 0

Related Questions