2013-05-12 13 views
6

Utilizzando ExtJS 4.2Capire come negozi modelli sono referenziati/loade/un'istanza in ExtJS 4.2 pattern MVC

Ho letto molti Documenti, Google, forum cercando di capire come i componenti di carico e dove metterli, come negozi, modelli , ect ma ancora confuso.

Questo è un esempio che sto cercando di far funzionare

Descrizione applicazione

Menu principale con i contatti, progetti, persone, ecc ecc, app primi carichi per visualizzare un statici data-driven, quindi utilizzare i clic non su Contatti che visualizza una griglia con l'elenco dei contatti. L'utente fa quindi clic su una riga di contatto e viene visualizzata la vista di modifica popup.

In contacteditview il contatto viene caricato nel modulo in aggiunta il modulo ha una casella combinata che carica il negozio ContactTypes. ContactType deve essere impostato sul valore di contatto per il record del contatto.

Qual è il modo comune per farlo considerando che si tratta di un'applicazione di grandi dimensioni e desidero solo caricare i dati quando è necessario, ovvero la visualizzazione viene visualizzata.

Ecco alcuni dei miei confusioni

1) È possibile definire tutti voi Controller, Negozi, modelli, Vista nel config app, ma poi tutto viene caricato indipendentemente dalla pagina che si sta guardando. Inoltre, se hai AutoLoad: true sui tuoi negozi, quindi chiama tutti i negozi sono fatti sul database anche se non stai guardando quella particolare vista.

2) Quando si specifica un negozio o un modello nella proprietà dei negozi o dei modelli nel controller, che cosa fa esattamente? Ti consente semplicemente di fare riferimento al negozio ma non di crearlo o lo crea o è solo impostando le funzioni getter e setter per comodità. Esempio se si specifica un negozio nella proprietà store del mio controller e se AutoLoad è true, tutti i dati vengono caricati senza bisogno di fare altro. Ma quello che voglio veramente è che quel negozio si carichi solo quando clicco su Contatto e viene visualizzata la vista elenco. Così ho impostato autoLoad: false e nella mia funzione di lista ottengo manualmente il negozio usando this.getStore('Contacts'). Funziona bene, ma qual è lo scopo dell'utilizzo di negozi e modelli di proprietà array del controller. Vedo nel debugger che se non utilizzo le proprietà del negozio/modello viene richiesta una richiesta per quei file js.

Scusa, so che questo è molto, ma è molto confuso per me e ho lottato per un po '.

3) Infine, il caricamento della griglia di contatti è attivo solo quando si fa clic sul pulsante Contatti impostando la funzione AutoLoad: false e caricamento manuale. Ora, quando un utente fa clic su modifica, il record viene caricato correttamente, ma come faccio a caricare la casella combinata e quindi selezionare il valore corretto. Penso che parte del mio problema sia capire come i modelli di negozi vengono caricati e istanziati. Nella mia proprietà del negozio combo ho specificato ContactType come negozio, ma ottengo un archivio errori undefined, quindi il file js non è caricato o il negozio non è istanziato.

Ecco il mio codice finora.

Codice App

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'], 
}); 

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

Contatti vedi lista

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

Contatti visualizzazione Modifica

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

Grazie per qualsiasi aiuto

+0

Hai trovato qualche risposta alla tua domanda? Sto affrontando problemi simili e sono confuso su come gli Store sono gestiti nel paradigma MVC di Ext.js. –

+0

No purtroppo no. Ho smesso di usare Extjs a causa di documenti non validi e non di un buon supporto e ora sto usando qooxdoo, è simile a Extjs e finora non ho avuto alcun problema più la documentazione e gli esempi sono molto migliori. Ed è una licenza LGPL completamente gratuita che significa che puoi usarla in prodotti commerciali. Dai un'occhiata a http://qooxdoo.org/. Il supporto è guidato dalla comunità ed è piuttosto buono, soprattutto se confrontato con il supporto Sencha. Ed è attivamente in fase di sviluppo + aggiornamenti del blog attivi. Solo il problema che ho avuto è stata la configurazione iniziale, comprendendo solo la creazione del progetto/creazione. – dan

risposta

2

Da non perdere con ExtJs. Lo so, potrebbe essere un dolore ...

per il vostro problema, ho risolto in questo modo:

ho una griglia che elencare i comuni d'Italia. Voglio filtrare per paese, regione e provincia, quindi metto tre combobox su un container agganciato. Nel controllore ho:

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

Nel controllore, ovviamente, ho altri ascoltatori per 'selezionare' evento caselle combinate di, in modo da poter filtrare e ricaricare combo in base ai valori selezionati.

seguito MVC picchiettio, i miei negozi sono simili a questo:

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

e modelli simili a:

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

E si fa riferimento nella mia griglia questo modo:

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

Speranza questo può aiutare.

ciao

+0

Apprezzo la risposta e la risposta, ma mi sono già trasferito e sono felice fino ad ora con qooxdoo, spero che questo aiuti qualcun altro! – dan

Problemi correlati