Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I never found a definitive answer on this from Sencha when I was getting started with MVC but I can tell you what I have been doing for a few apps successfully. </p> <p>I create and load my stores according to how they are used. That seems to have divided into three different categories for me:</p> <ol> <li><p>Stores that apply to the whole app</p></li> <li><p>Stores that apply to all instances of a view</p></li> <li><p>Stores that are tied to a single view <em>instance</em></p></li> </ol> <p><strong>1. Stores that apply to the whole app</strong></p> <p>I usually have a "Main" controller that handles the framework of my app, things like keyboard navigation, the main menu, etc.</p> <p>Stores that fall into the first category above go in this "Main" controller's <code>stores</code> array. If these stores are not dependent on another store then I simply make them <code>autoLoad: true</code> and am done with them. But in cases where they are dependent on another stores data then I add a listener to the parent store to load the dependent store inside the parent's <code>onLoad</code> event.</p> <p>An example of some of the stores I find falling into this first category are reference stores that I use in comboboxes throughout the app, usually in many different types of views. These are usually configured with <code>autoLoad: true</code> and then I never load them again for that user's session. Whenever I need a combobox that uses the reference store, I can set it up like this:</p> <pre><code>{ xtype: 'combobox', allowBlank: false, forceSelection: true, store: Ext.getStore('SomeReferenceStore'), queryMode: 'local', // this makes sure the store doesn't reload valueField: 'id', displayField: 'name' } </code></pre> <p>To give an example of two stores that both fall into the first category, with one being dependent on another: </p> <p>In one of my apps I have a dynamic number of user permissions, when a user logs into the app I needed to fetch the different permissions and modify the <code>User</code> model to include a boolean field for each of these different permissions:</p> <pre><code>Ext.define('MyApp.controller.Main', { extend: 'Ext.app.Controller', models: [ 'User', 'Reference', // etc... ], stores: [ 'CurrentUser', 'PermissionRef', // this is "autoLoad: true" // etc... ], init: function() { var me = this; // update the user model and load the user me.getPermissionRefStore().on('load', function(store, records) { var model = me.getUserModel(), fields = model.prototype.fields.getRange(); // append the permissions onto the User model fields Ext.each(records, function(permission) { fields.push({ name: permission.get('name'), type: 'bool', }); }); // update the user model with the permission fields model.setFields(fields); // load the current user me.getCurrentUserStore().load(); // other stuff... }); // other stuff... } }); </code></pre> <p>With this, whenever I need a reference to the user and what permissions he has available I simply call:</p> <pre><code>var user = Ext.getStore('CurrentUser').first(); </code></pre> <p>Sometimes a view will also be dependent on a store being loaded. For example my main menu items are determined by a database table, in that case I would include an <code>onLoad</code> listener the same way (inside the controller's <code>init</code> function):</p> <pre><code>// create the menu once we know what menu items are available me.getMenuStore().on('load', function(store) { me.getViewport().add(Ext.widget('mainpanel')); }); </code></pre> <p>The <code>MyApp.store.Menu</code> itself would be configured with <code>autoLoad: true</code>.</p> <p><strong>2. Stores that apply to all instances of a view</strong></p> <p>I create and load these just like the first category only I put them in the specific <em>view</em> controller's <code>stores</code> array instead of the "Main" controller <code>stores</code> array.</p> <p>Then it's the same basic concept, some are <code>autoLoad: true</code> some are not if they depend on another store's data.</p> <p>For the one's that are not <code>autoLoad: true</code> they get loaded somewhere inside the controller's <code>init</code> function or as the result of some event being fired.</p> <p><strong>3. Stores that are tied to a single view <em>instance</em></strong></p> <p>Here I may go against the MVC grain, but there really is no better place for a store that applies to a single instance of a view then inside the view itself. </p> <p>In most cases I don't even put these stores in the view controller's <code>stores</code> array. I just create and load them inside the view's <code>initComponent</code> function. As a result of this, when the view gets destroyed, there is no more reference to the store so the store will also get destroyed. That helps slim down on resources for stores that could get created many times.</p> <p>For example, say you have a <code>MyApp.view.UnicornWeightGrid</code> that extends a <code>gridpanel</code> and shows the progressive weight of a unicorn over time. A user can open a <code>UnicornWeightGrid</code> for all the unicorns in the realm for comparison and cross-reference purposes. There will be as many different instances of the <code>UnicornWeightStore</code> as there are instances of the <code>UnicornWeightGrid</code>.</p> <p>The view could be defined like this:</p> <pre><code>Ext.define('MyApp.view.UnicornWeightGrid', { extend: 'Ext.grid.Panel', alias: 'widget.unicornweight', requires: [ 'MyApp.model.UnicornWeight' ], closable: true, initComponent: function() { var me = this; me.store = Ext.create('Ext.data.Store', { model: 'MyApp.model.UnicornWeight', proxy: { type: 'ajax', url: 'unicorns/weight', extraParams: { name: me.unicornName } } }); me.store.load(); }); }); </code></pre> <p>Then whenever we want to get a different <code>UnicornWeightGrid</code> we can simply call:</p> <pre><code>var grid = Ext.widget('unicornweight', { unicornName: someUnicornNameVariable }); myTabPanel.add(grid); </code></pre> <p>Any <code>onLoad</code> listeners I need on stores that are defined in a view, I also attach inside the view. So I don't really need a reference anywhere else.</p> <p>With all that said, this is by no means the only way to set-up your stores. </p> <p>I have found this to be the most workable way to handle stores consistently in creating a few different ExtJS "MVC" apps, but I sometimes do it differently also in "special" cases. </p> <p>You should keep in mind that "MVC" is pretty loose design pattern, it is defined and implemented differently in almost every single framework I've used. So you can pretty much do whatever works best for you.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload