1

a) Here's a JS fiddle to help show what's happening: http://jsfiddle.net/CKpPW/ b) To replicate the issue, select the first drop down and notice how the full name appears. Then expand the second drop down and notice how the display of the first drop down goes away.

My assumption is that this happens because both comboboxes use the same store so when a filter is applied to the store it applies to everything, and thus when that record no longer exists it defaults back to whatever the value is.

Is there anyway to make that not happen, aka even after a filter on a store the data in the combobox stays the same. I can't seem to find any details on dualing comboboxes like this.

Here's the listener that needs to happen on expand as I need the ability to filter each combobox differently:

 listeners: {
     expand: {
         fn: function(){
             names.clearFilter(true);
            names.filter('id', 1);                
        }
    }
},
Aram Papazian
  • 2,453
  • 6
  • 38
  • 45

1 Answers1

1

Indeed, you're not supposed to share stores between components. That may be counter-intuitive, but store do not represent the whole data, but only the subset the component is currently working with. The interface to the whole data is the proxy.

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

So if you want to share data, what you need to share is the proxy, not the store.

Here's, for example, how to fix your fiddle:

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()
});

Now, your next question will probably be about how to get your sever-side data into that client-side memory proxy... Unfortunately, the framework doesn't offer any solution out of the box.

The most straightforward way is probably to load your data once with a regular AJAX request, put it into a memory proxy, and pass this proxy to all your stores.

Or you can get creative and try to implement your own proxy that mixes loading from the server and caching on the client. That's quite simple to achieve by overriding the Memory proxy, but soon enough you'll be running into a bunch of tough questions... How to handle the caching for operations with different params? How to handle request params at all? What about the other CRUD operations, beyond read? Etc. If you want to give it a try anyway, you can look at this extension for inspiration (it is written for Touch, so you can't use it directly, but the principles are the same for ExtJS).

rixo
  • 23,815
  • 4
  • 63
  • 68
  • Technically I didn't put all the data I had above, but I already do have a proxy setup, but it's setup on the models. Wouldn't having a proxy on a model do roughly the same thing? Or is there some parameter I would need to set for it to use a proxy each time a combobox is created? – Aram Papazian Jun 21 '13 at 17:14
  • You do want your proxy to be shared, so having it configured in the model is a good thing. What you want to avoid is sharing a store instance, like you do in your fiddle. Maybe my code example didn't make it clear that 2 different stores will be created, I've edited it to make it obvious. – rixo Jun 21 '13 at 17:42
  • So I'd have to create a new store for each combobox then? Is there not a dynamic way to make that happen such that all comboboxes would get a new store rather than the current global store? I'm gonna mess around with the 'store' param in the combobox, but not sure if that would do much. – Aram Papazian Jun 21 '13 at 18:04
  • Side Note: I'm using Architect which makes it slightly more confusing getting things to work the way you want sometimes. – Aram Papazian Jun 21 '13 at 18:05
  • Yes, the store config option will do that. If you set a config object in there (and not an instantiated store!), then Ext will create a new store with that config for each combo. In fact, that's what the previous version of my code was doing (you may still view the edited version by clicking the "edited..." link). – rixo Jun 21 '13 at 18:08
  • Well, the issue is that Architect only allows strings for the 'store' section =/ Is there a secondary method? Or would creating a new store be the only option? – Aram Papazian Jun 21 '13 at 19:09
  • Really? That's a surprising decision from the Architect developers... Maybe you can override the `initComponent` method of the combo and create the store in there. – rixo Jun 21 '13 at 19:39
  • It was weird. You can either change it to a store or an array, both of which it converts into a string. I've never really done overriden initComponent. Can you walk me through how I would do that (or where I can find a good tutorial)? [Side note: I'll be out for the next 2 days, so I won't be able to respond for a couple days. I'll try this method out on Monday. Thanks for all your help so far =) ] – Aram Papazian Jun 21 '13 at 19:49
  • In [this answer](http://stackoverflow.com/a/16416858/1387519), there are examples both for overriding or extending a component, and its `initComponent` method. The principles are the same for combo. – rixo Jun 21 '13 at 19:57
  • Took me a few different tries, but I got it to work properly. Thanks =) – Aram Papazian Jun 24 '13 at 20:30