1. #1
    Sencha User
    Join Date
    Apr 2011
    Posts
    65
    Vote Rating
    1
    c089 is on a distinguished road

      0  

    Default How to set filters on a store when using Ext.define?

    How to set filters on a store when using Ext.define?


    Hey, I'm having a little trouble defining my stores: The Store API docs define a store with filters like this:
    Code:
    var store = new Ext.data.Store({
        model: 'User',
        sorters: [
            {
                property : 'age',
                direction: 'DESC'
            },
            {
                property : 'firstName',
                direction: 'ASC'
            }
        ],
    
        filters: [
            {
                property: 'firstName',
                value   : /Ed/
            }
        ]
    });
    When I try to do the same using the MVC architecture and Ext.define it does not work:
    Code:
    Ext.define('TT.store.UnscheduledEventsStore', {
        autoLoad: true,
        extend: 'Ext.data.Store',
        model: 'TT.model.EventModel',
        filters: [
            { property: 'weekDay', value: '' }
        ]
    });
    It seems to work with *most* options and properties, but I just can't define filters like that.

    So this test will fail with expected 1, but was 0:
    Code:
        "test store has its filter applied": function () {
            assertEquals(1, this.store.filters.length);
        },
    But it gets worse: If I apply another filter just before that assert, it fails with "epxected 1, but was 2", so there I have BOTH filters now:
    Code:
        "test store has its filter applied": function () {
            this.store.filter('foo', 'bar');
            assertEquals(1, this.store.filters.length);
        },
    Update: If I do the same with "sorters", it works. It's really only "filters" that I can't define like this....

    Thanks, Chris

  2. #2
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Posts
    1,347
    Vote Rating
    134
    dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all

      0  

    Default


    Hi Chris,

    The filters are stored in a MixedCollection, keyed by 'id'. Filters are added to this collection in the AbstractStore constructor and then again in the filter() method. This may have been a bug where the initial population of the filters collect was lazy, but the code appears to do what you would expect now.

    If this does not work in the 4.0 release version, let us know. You could step into the filter() call to see the sequence if you like. If this is still a problem, you could work around it by adding the filters in your constructor.
    Don Griffin
    Ext JS Development Team Lead

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  3. #3
    Sencha User
    Join Date
    Apr 2011
    Posts
    65
    Vote Rating
    1
    c089 is on a distinguished road

      0  

    Default


    In ext-all-debug.js line 43023 there is this code:
    Code:
    me.filters = Ext.create('Ext.util.MixedCollection');
    me.filters.addAll(me.decodeFilters(config.filters));
    Using the debugger I found that before that first line, me.__proto__.filters was set if I specified the filters like this:
    Code:
    Ext.define(...
        extend: 'Ext.data.Store', ...
       filters: [
             { property: 'weekDay', value: '' }
            ]
        }
    If I insteead do this:
    Code:
    Ext.define(...
        extend: 'Ext.data.Store', ...
        config: {
            filters: [
                { property: 'weekDay', value: '' }
            ]
        }
    ..then the filters are in me.__proto__.config.filters. But they are never in the config object that is passed to the constructor. Same for the model and all other properties. Now the other properties are set like this:
    Code:
    me.setProxy(config.proxy || me.proxy || me.model.getProxy());
    As you can see for the proxy it falls back to me.proxy if it's not in the config object, but not for the filters and that seems to be the reason why they are lost. I don't know, however, why they are never part of the config object that is passed to the constructor...

  4. #4
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Posts
    1,347
    Vote Rating
    134
    dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all

      0  

    Default


    In the case of the proxy, the line:

    Code:
            me.setProxy(config.proxy || me.proxy || me.model.getProxy());
    is a tad redundant. The config variable is the constructor argument and its properties have been copied on to "this" (aka "me") by this point. So this should not have had "config.proxy ||" at all.

    In most cases the config object passed to the constructor is simply merged on to the component like this:

    Code:
    constructor: function (config) {
        Ext.apply(this, config);
        // other things
    }
    After the apply, whether the property is found in the prototype or came in through config is ignored (though you do see things like the above occasionally).

    In your example, passing a property named config in the config object is not what you want to do. The apply blindly copies your property named config onto this store but the code never looks at it because it is looking for properties on this (or a prototype).

    So this code looks right:

    Code:
    Ext.define('...', {
        extend: 'Ext.data.Store',
        filters: [
            { property; 'weekDay', value: '' }
        ]
    });
    Are you having problems with that form?
    Don Griffin
    Ext JS Development Team Lead

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  5. #5
    Sencha User
    Join Date
    Apr 2011
    Posts
    65
    Vote Rating
    1
    c089 is on a distinguished road

      0  

    Default


    Yes, in this case the "config" passed to the constructor is still empty. Filters is set on "me" by some other way. I guess that the "config" which is passed to the ctor is only used when you use Ext.create() while the options set using Ext.define get into that object in some other way. The filters that are set using Ext.define are availableas "me.__proto__.filters" in the constructor, but they are overwritten by the line I quoted above (which creates the MixedCollection).

    BTW, the release notes mention your new unit testing suite. Is there a way to execute this suite and add our own tests? That way, I could provide a minimal unit test that you guys could run which would make reporting bugs much easier.

  6. #6
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Posts
    1,347
    Vote Rating
    134
    dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all

      0  

    Default


    Hi Gabrielle,

    Indeed if you (try to) configure groupers in the prototype, you will have problems. I will log a bug for this one.

    Can you post a snippet of your code?
    Don Griffin
    Ext JS Development Team Lead

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  7. #7
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Posts
    1,347
    Vote Rating
    134
    dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all

      0  

    Default


    Hi Gabrielle,

    I would try this (because neither groupers nor groupField are properly respected in the prototype chain):

    Code:
    Ext.define('IS.store.Persons', {
        extend: 'Ext.data.ArrayStore',
        model: 'IS.model.Person',
    
        constructor: function (config) {
            config = config || {};
            if (!config.groupField) {
                config.groupField = 'age';
            }
    
            this.callParent([config]);
        }
    });
    Again, this is a bug in my opinion, but until the next point release at a minimum, a work around like the above is the way to go. The above will continue to work even when this is corrected.
    Don Griffin
    Ext JS Development Team Lead

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  8. #8
    Sencha User
    Join Date
    Apr 2007
    Posts
    172
    Vote Rating
    1
    medusadelft is on a distinguished road

      0  

    Default


    Quote Originally Posted by gabrielle View Post
    Hi Don,

    I have tried several pieces of code (e.g. with our without a config property) but none worked. Here is the simplest:

    < snip >
    Don/Gabrielle,

    I have exactly the same problem. And I have a similar problem with 'ux.searchfield' that extends the triggerfield (in a toolbar). me.store is undefined (although the store-property is set). Can I try a similair solution like the one Don provided for the groupField?
    Code:
    Ext.define('EX.view.member.List' ,{ 
        extend: 'Ext.grid.Panel', 
        alias : 'widget.memberlist', 
     
        title : 'All Members', 
     
    	store: 'Members',
    	features: [
            {
                ftype: 'grouping'
            }
        ],
    
    	dockedItems: [{
    		dock: 'top',
    		xtype: 'toolbar',
    		items: [
    			{
    				xtype: 'searchfield'
    				,store: Ext.getStore('storeMembers')
    				,id: 'member_search'
    				,emptyText: 'Search'
    			}
    		]
    	}],
    
        initComponent: function() { 
            this.columns = [ 
                {header: 'Country',  dataIndex: 'country_id',flex: .3},
                {header: 'Name',  dataIndex: 'lastname', flex: 1},
                {header: 'Gender', dataIndex: 'gender', flex: .3},
                {header: 'Email', dataIndex: 'email_address', flex: 1} 
            ]; 
    
            this.callParent(arguments); 
        } 
    });
    Thanks in advance,
    Maurice.

  9. #9
    Sencha User
    Join Date
    Apr 2011
    Posts
    65
    Vote Rating
    1
    c089 is on a distinguished road

      0  

    Default


    Still looking for a solution/workaround to the filters problem. I tried setting them in the constructor, but that just got me into more trouble with stuff being null or undefined :/

  10. #10
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Posts
    1,347
    Vote Rating
    134
    dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all dongryphon is a name known to all

      0  

    Default


    Looks like you've done a great analysis here. If you could post the complete code you are using (w/o the "config" property) and the test code, I'll take a look. Please make it as direct as possible to paste your code into a test page/JS file so I don't introduce a problem in reconstruction.
    Don Griffin
    Ext JS Development Team Lead

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

Similar Threads

  1. Store and multiple filters
    By steffenk in forum Ext 1.x: Help & Discussion
    Replies: 9
    Last Post: 28 Oct 2012, 11:48 PM
  2. How to add filters to a store?
    By blessan in forum Sencha Touch 1.x: Discussion
    Replies: 20
    Last Post: 16 May 2011, 11:26 AM
  3. Grouping Store with Grid Filters?
    By Sesshomurai in forum Ext 3.x: Help & Discussion
    Replies: 0
    Last Post: 28 Oct 2010, 12:20 PM
  4. Two comboboxes, one store different filters?
    By Joche in forum Ext 2.x: Help & Discussion
    Replies: 2
    Last Post: 22 Jun 2008, 11:37 PM

Thread Participants: 2