ExtJS单个Store实现双ComboBox联动动态加载数据方案咨询
Absolutely! Using a single Store for both ComboBoxes is not only possible but also the recommended approach—it keeps your data centralized and avoids redundant Stores. Here’s how to do it properly, depending on your Ext JS version:
Using ChainedStores (Ext JS 5+)
ChainedStores are perfect here because they create filtered "views" of your main Store without modifying the original data. This means each ComboBox can have its own filtered version of the same underlying data.
Step 1: Create Your Main Store
First, define a single Store with all your data:
Ext.define('MyApp.store.AllItems', { extend: 'Ext.data.Store', alias: 'store.allitems', fields: ['id', 'type', 'name'], data: [ {id: 1, type: 'Electronics', name: 'Laptop'}, {id: 2, type: 'Electronics', name: 'Phone'}, {id: 3, type: 'Furniture', name: 'Chair'}, {id: 4, type: 'Furniture', name: 'Table'}, {id: 5, type: 'Clothing', name: 'Shirt'} ] });
Step 2: Build the First ComboBox (Type Selector)
This ComboBox uses a ChainedStore to show only unique type values from the main Store:
{ xtype: 'combobox', fieldLabel: 'Type', reference: 'typeCombo', displayField: 'type', valueField: 'type', store: { type: 'chained', source: 'allitems', filters: [{ filterFn: function(record, recordId) { // Only keep the first occurrence of each type return !this.getRange().some(function(r) { return r.get('type') === record.get('type') && r.getId() !== recordId; }); } }] }, listeners: { change: function(combo, selectedType) { var itemCombo = combo.up('form').down('#itemCombo'); var filteredStore = itemCombo.getStore(); // Clear existing filters before applying new ones filteredStore.clearFilter(); if (selectedType) { filteredStore.filter('type', selectedType); } } } }
Step 3: Build the Second ComboBox (Filtered Items)
This ComboBox uses another ChainedStore linked to the main Store, which we filter dynamically based on the first ComboBox's selection:
{ xtype: 'combobox', fieldLabel: 'Item', itemId: 'itemCombo', displayField: 'name', valueField: 'id', store: { type: 'chained', source: 'allitems' } }
For Older Ext JS Versions (Pre-5)
If you’re using an older version without ChainedStores, you can still use one main Store. Here’s how:
- Populate a small memory Store for the first ComboBox with unique
typevalues (derived from the main Store). - When the first ComboBox changes, filter the main Store directly (or a cloned copy) for the second ComboBox.
Example code for the first ComboBox's Store population (add this to your main Store's load listener):
load: function(mainStore) { // Extract unique types from the main Store var uniqueTypes = Ext.Array.unique(mainStore.getRange().map(function(record) { return record.get('type'); })); // Populate the type selector Store var typeStore = Ext.getStore('typeStore'); typeStore.removeAll(); uniqueTypes.forEach(function(type) { typeStore.add({type: type}); }); }
Then, in the first ComboBox's change listener, filter the main Store for the second ComboBox:
change: function(combo, selectedType) { var itemStore = Ext.getStore('allitems'); itemStore.clearFilter(); if (selectedType) { itemStore.filter('type', selectedType); } }
Note: If other components use the main Store, filtering it directly might affect them. To avoid this, clone the main Store for the second ComboBox instead.
内容的提问来源于stack exchange,提问作者Shiromi

