Understanding how warehouse models are referenced / loade / are created in Extjs 4.2 MVC pattern

Using Extjs 4.2

I read a lot of documents, google, forums trying to understand how components load and where to place them, such as stores, models, ect, but still confusing.

This is an example I'm trying to get

Application description

Main menu with contacts, projects, people, etc. etc. etc., first loads the application to display a static, independent of data, and then clicks on contacts, which displays a grid with a list of contacts. Then the user clicks on the contact line and a popup edit window is displayed.

In contacteditview, the contact is loaded into the form, in addition, the form has a combobox that loads the ContactTypes store. ContactType must be set to contacttype for this contact record.

What is the general way to do this, given this large application, and I only want to download the data when necessary, i.e. display view.

Here are some of my notes.

1) You can define all the controllers, stores, models, views in the application configuration, but then everything loads regardless of what page you look at. In addition, if you have autoLoad: true in your stores, then calls to all stores are made in the database, even if you are not looking at this particular view.

2) When you specify the storage or model in the properties of the stores or models of your controller, what exactly does this do? It just allows you to easily reference the store, but doesnโ€™t actually create it or create it, or it just sets up getter and setter functions for convenience. Example, if I specify the storage in the storage property of my controller and set autoLoad to true, all data is loaded without having to do anything else. But I really want this store to load only when I click "Contact" and the list view is displayed. So I set autoLoad: false and in my list function I manually get the store using this.getStore('Contacts') . This works great, but the goal is to use storage properties and controller array models. I see in the debugger that if I do not use the store / model properties, a request is received for these js files.

Sorry, I know that this is a lot, but it really confuses me and fights with it for a while.

3) Finally, I load the contacts grid only when you click the Contacts button, setting autoLoad: false and manual loading. Now, when the user clicks on the edit, the record loads fine, but how do I get the combobox to load, and then select the correct value. I think part of my problem is understanding how store models are loaded and created. In my combobox property store, I specified ContactType as the store, but I got the undefined error store, so either the js file is not loaded or the store is not created.

Here is my code.

Application code

 Ext.Loader.setConfig({ enabled: true, paths: { 'Ext.ux': "lib/extux", 'Wakanda': "lib/extux/wakanda" } }); Ext.application({ name: 'SimplyFundraising', autoCreateViewport: true, requires: ['Ext.ux.Router', // Require the UX 'Wakanda.model'], controllers: ['Contacts'], }); 

Contact controller

 Ext.define('SimplyFundraising.controller.Contacts', { extend: 'Ext.app.Controller', views: ['contacts.List', 'contacts.Edit'], init: function () { this.control({ 'contactslist': { itemdblclick: this.editContact, removeitem: this.removeContact }, 'contactslist > toolbar > button[action=create]': { click: this.onCreateContact }, // 'contactsadd button[action=save]': { // click: this.doCreateContact // }, 'contactsedit button[action=save]': { click: this.updateContact } }); }, list: function () { var mystore = this.getStore('Contacts') mystore.load(); // mystore.proxy.extraParams = { $expand: 'ContactType'}; // var User = this.getContactModel(); // User.load(258, { // success: function (user) { // console.log("Loaded user 258: " + user.get('lastName')); // } // }); }, editContact: function (grid, record) { var view = Ext.widget('contactsedit'); view.down('form').loadRecord(record); this.addnew = false }, removeContact: function (Contact) { Ext.Msg.confirm('Remove Contact ' + Contact.data.lastName, 'Are you sure?', function (button) { if (button == 'yes') { this.getContactsStore().remove(Contact); } }, this); }, onCreateContact: function () { var view = Ext.widget('contactsedit'); this.addnew = true }, // doCreateContact: function (button) { // var win = button.up('window'), // form = win.down('form'), // values = form.getValues(), // store = this.getContactsStore(); // if (form.getForm().isValid()) { // store.add(values); // win.close(); // } // }, updateContact: function (button) { var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues(), store = this.getContactsStore(); if (form.getForm().isValid()) { if (this.addnew == true) { store.add(values); } else { record.set(values); } win.close(); } } }); 

List of contacts

 Ext.define('SimplyFundraising.view.contacts.List', { extend : 'Ext.grid.Panel', xtype : 'contactslist', title : 'All Contacts', store : 'Contacts', autoHeight: true, autoScroll : true, viewConfig : { loadMask : true }, initComponent : function() { this.tbar = [{ text : 'Create Contact', action : 'create' }]; this.columns = [{ header : 'Id', dataIndex : '__KEY', width : 50 }, { header : 'First Name', dataIndex : 'firstName', flex : 1 }, { header : 'Middle Name', dataIndex : 'middleName', flex : 1 }, { header : 'Last Name', dataIndex : 'lastName', flex : 1 }, { header : 'Type', dataIndex : 'ContactType.name', flex : 1 }]; this.addEvents('removeitem'); this.actions = { removeitem : Ext.create('Ext.Action', { text : 'Remove Contact', handler : function() { this.fireEvent('removeitem', this.getSelected()) }, scope : this }) }; var contextMenu = Ext.create('Ext.menu.Menu', { items : [this.actions.removeitem] }); this.on({ itemcontextmenu : function(view, rec, node, index, e) { e.stopEvent(); contextMenu.showAt(e.getXY()); return false; } }); this.callParent(arguments); }, getSelected : function() { var sm = this.getSelectionModel(); var rs = sm.getSelection(); if (rs.length) { return rs[0]; } return null; } }); 

Contacts edit view

 Ext.define('SimplyFundraising.view.contacts.Edit', { extend: 'Ext.window.Window', xtype: 'contactsedit', title: 'Edit Contacts', layout: 'fit', autoShow: true, initComponent: function () { this.items = [ { xtype: 'form', bodyStyle: { background: 'none', padding: '10px', border: '0' }, items: [ { xtype: 'textfield', name: 'firstName', allowBlank: false, fieldLabel: 'Name' }, { xtype: 'textfield', name: 'lastName', allowBlank: false, fieldLabel: 'Last Name' }, { xtype: 'combobox', fieldLabel: 'Contact Type', name: 'contactType', store: 'ContactTypes', displayField: 'name', typeAhead: true, queryMode: 'local', emptyText: 'Select a type...' } ] } ]; this.buttons = [ { text: 'Save', action: 'save' }, { text: 'Cancel', scope: this, handler: this.close } ]; this.callParent(arguments); } }); 

Thanks for any help

+6
source share
1 answer

Do not miss ExtJs. I know it could be a pain ...

For your problem, I solved like this:

I have a grid listing Italian municipalities. I want to filter by country, region and province, so I put three collections on a docked container. In the controller, I:

  ,init : function (application) { this.control({ ,"#municipalitiesGrid": { afterrender: this.onMunicipalitiesGridAfterRender } }); } ,onMunicipalitiesGridAfterRender: function(grid, opts) { console.info('GVD.controller.Geo->onMunicipalitiesGridAfterRender'); var store = grid.getStore(), comboCountriesMunicipalities = this.getComboCountriesMunicipalities(), storeCountries = comboCountriesMunicipalities.getStore(), comboRegionsMunicipalities = this.getComboRegionsMunicipalities(), storeRegions = comboRegionsMunicipalities.getStore(), comboProvincesMunicipalities = this.getComboProvincesMunicipalities(), storeProvinces = comboProvincesMunicipalities.getStore(); store.clearFilter(true); storeCountries.clearFilter(true); storeRegions.clearFilter(true); storeProvinces.clearFilter(true); storeRegions.filter("idCountry", 114); // 114 = Italia storeProvinces.filter("idRegion",8); // 8 = Emilia Romagna store.filter("idProvince", 37); // 37 = Bologna storeCountries.load({ scope: this, callback: function(records, operation, success) { storeRegions.load({ scope: this, callback: function(records, operation, success) { storeProvinces.load({ scope: this, callback: function(records, operation, success) { store.load({ scope: this, callback: function(records, operation, success) { comboCountriesMunicipalities.setValue(114); // 114 = Italia comboRegionsMunicipalities.setValue(8); // 8 = Emilia Romagna comboProvincesMunicipalities.setValue(37); // 37 = Bologna } }); } }); } }); } }); } 

In the controller, of course, I have other listeners for the select comboboxes event, so I can filter and reload the combos according to the selected values.

Following the MVC example, my stores are similar to the following:

 Ext.define('GVD.store.Municipalities', { extend: 'Ext.data.Store' ,constructor: function(cfg) { console.info('GVD.store.Municipalities->constructor'); var me = this; cfg = cfg || {}; me.callParent([Ext.apply({ autoLoad: false ,autoSync: true ,model: 'GVD.model.Municipalities' ,pageSize: 20 }, cfg)]); } }); 

And models similar to:

 Ext.define('GVD.model.Municipalities', { extend: 'Ext.data.Model', fields: [ { name: 'id', type: 'int' }, { name: 'idIstat', type: 'int' }, { name: 'idCountry', type: 'int' }, { name: 'idRegion', type: 'int' }, { name: 'idProvince', type: 'int' }, { name: 'name', type: 'string' }, { name: 'chief_town', type: 'boolean' }, { name: 'altitude_zone', type: 'int' }, { name: 'altitude', type: 'int' }, { name: 'coastal', type: 'int' }, { name: 'mountain', type: 'int' }, { name: 'surface', type: 'double' }, { name: 'residents', type: 'int' }, { name: 'icon', type: 'string' } ] ,proxy: { api: { create: 'Municipalities.create' ,destroy: 'Municipalities.destroy' ,read: 'Municipalities.read' ,update: 'Municipalities.update' } ,reader: { root: 'data' ,totalProperty: 'totalCount' ,type: 'json' } ,type: 'direct' } }); 

And referenced in my grid like this:

 Ext.define('GVD.view.system.geo.ListMunicipalities', { autoScroll: true ,constrain: true ,dockedItems: [{ xtype: 'topBar' },{ items: [{ allowBlank: true ,fieldLabel: 'Nazione' ,flex: 1 ,id: 'comboCountriesMunicipalities' ,labelAlign: 'right' ,labelWidth: 50 ,listConfig: { getInnerTpl: function() { return '<img src="resources/images/countries/16/{icon}16.gif" align="left">&nbsp;&nbsp;{italianName}'; } } ,store: Ext.create('GVD.store.Countries', {pageSize: 999}) ,xtype: 'comboCountries' },{ allowBlank: true ,fieldLabel: 'Regione' ,flex: 1 ,id: 'comboRegionsMunicipalities' ,labelAlign: 'right' ,labelWidth: 50 ,listConfig: { getInnerTpl: function() { return '<img src="resources/images/regions/16/{icon}16.gif" align="left">&nbsp;&nbsp;{name}'; } } ,store: Ext.create('GVD.store.Regions', {pageSize: 999}) ,xtype: 'comboRegions' },{ allowBlank: true ,fieldLabel: 'Provincia' ,flex: 1 ,id: 'comboProvincesMunicipalities' ,labelAlign: 'right' ,labelWidth: 50 ,listConfig: { getInnerTpl: function() { return '<img src="resources/images/provinces/16/{icon}16.gif" align="left">&nbsp;&nbsp;{name}'; } } ,store: Ext.create('GVD.store.Provinces', {pageSize: 999}) ,xtype: 'comboProvinces' }] ,layout: 'hbox' ,xtype: 'container' }, { dock: 'bottom' ,itemId: 'municipalitiesPagingToolbar' ,store: 'Municipalities' ,xtype: 'pagingToolBar' }] ,extend: 'Ext.window.Window' ,height: 400 ,icon: 'resources/images/GVD/municipalities16.png' ,id: 'listMunicipalities' ,items: [{ columns: [{ xtype: 'rownumberer' },{ align: 'right' ,dataIndex: 'id' ,format: '000' ,renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { return '<img src="resources/images/municipalities/16/'+record.data.icon+'16.gif" align="left">&nbsp;&nbsp;'+record.data.id; } ,text: 'Id' ,width: 70 ,xtype: 'numbercolumn' },{ align: 'right' ,dataIndex: 'idIstat' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '000000000' ,text: 'Istat' ,width: 80 ,xtype: 'numbercolumn' },{ dataIndex: 'name' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'string' } ,flex: 1 ,text: 'Denominazione' ,xtype: 'gridcolumn' },{ dataIndex: 'chief_town' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,text: 'Capoluogo' ,width: 40 ,xtype: 'numbercolumn' },{ dataIndex: 'altitude_zone' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '0' ,text: 'Zona alt.' ,width: 40 ,xtype: 'numbercolumn' },{ align: 'right' ,dataIndex: 'altitude' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '0000' ,text: 'Altitudine' ,width: 40 ,xtype: 'numbercolumn' },{ dataIndex: 'coastal' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '0' ,text: 'Costiero' ,width: 40 ,xtype: 'numbercolumn' },{ dataIndex: 'mountain' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '0' ,text: 'Montano' ,width: 40 ,xtype: 'numbercolumn' },{ align: 'right' ,dataIndex: 'surface' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '000,000.00' ,text: 'Superficie' ,xtype: 'numbercolumn' },{ align: 'right' ,dataIndex: 'residents' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'numeric' } ,format: '0,000,000' ,text: 'residenti' ,xtype: 'numbercolumn' },{ dataIndex: 'icon' ,editor: { allowBlank: false, selectOnFocus: true } ,filter: { type: 'string' } ,flex: 1 ,text: 'Icona' ,xtype: 'gridcolumn' }] ,columnLines: true ,emptyText: '<font color="red"><b>Nessun comune in archivio</b></font>' ,features: [ Ext.create('GVD.ux.grid.FiltersFeature', { encode: true, ftype: 'filters', local: false, menuFilterText: 'Filtro' }) ] ,id: 'municipalitiesGrid' ,plugins: [ Ext.create('Ext.grid.plugin.RowEditing', { ptype: 'rowediting' }) ] ,selModel: { selType: 'checkboxmodel', mode: 'MULTI' },store: 'Provinces' ,store: 'Municipalities' ,viewConfig: { loadingText: 'Caricamento dati' ,stripeRows: true ,trackOver: true } ,xtype: 'grid' }] ,layout: { align: 'stretch' ,type: 'vbox' } ,margin: '0 0 2 0' ,maximizable: true ,minimizable: true ,requires: [ 'GVD.ux.combo.Countries' ,'GVD.ux.combo.Provinces' ,'GVD.ux.combo.Regions' ,'GVD.ux.PrintButton' ,'GVD.ux.toolbar.BottomBar' ,'GVD.ux.toolbar.PagingToolBar' ,'GVD.ux.toolbar.TopBar' ] ,singleWindow: true ,title: 'Elenco comuni' ,tools: [ { xtype: 'printButton', title: 'Elenco Comuni', tooltip: 'Stampa elenco' } ,{ type: 'help', xtype: 'tool', tooltip: 'Guida sulla funzione' } ] ,width: 760 }); 

Hope this helps.

goodbye

+2
source

Source: https://habr.com/ru/post/944818/


All Articles