2012-08-24 10 views
6

Considerare un'applicazione complessa in cui si dispone di logica di filtro personalizzata e diverse modalità di caricamento; caricamento ritardato quando nascosto, nessun caricamento quando è nascosto, ma carico quando viene mostrato e ricaricato quando i filtri personalizzati vengono modificati ecc.In un'app MVC Ext JS 4, quale dovrebbe essere responsabile del caricamento dei negozi?

Quale parte dell'applicazione mvc dovrebbe essere responsabile del caricamento e come collegarlo tutto?

risposta

15

Non ho mai trovato una risposta definitiva su questo da Sencha quando stavo iniziando con MVC, ma posso dirvi cosa ho fatto per alcune app con successo.

Creo e carica i miei negozi in base a come vengono utilizzati. Che sembra essere suddivisi in tre diverse categorie per me:

  1. Negozi che si applicano a tutto l'app

  2. Negozi che si applicano a tutte le istanze di una vista

  3. negozi che sono legati a una singola immagine esempio

1. magazzini th al applicarsi a tutta l'app

Di solito ho un regolatore "principale" che gestisce il quadro della mia app, cose come la navigazione da tastiera, il menu principale, ecc

Negozi che rientrano nella prima categoria di cui sopra andare in questo array "principale" del controller stores. Se questi negozi non dipendono da un altro negozio, li faccio semplicemente con lo autoLoad: true e ho finito con loro. Ma nei casi in cui dipendono da altri dati dei negozi, aggiungo un listener all'archivio principale per caricare il negozio dipendente all'interno dell'evento del genitore.

Un esempio di alcuni negozi che trovo rientrare in questa prima categoria sono negozi di riferimento che utilizzo nelle caselle combinate in tutta l'app, di solito in molti diversi tipi di visualizzazioni. Questi sono solitamente configurati con autoLoad: true e quindi non li carico mai più per la sessione dell'utente.Ogni volta che ho bisogno di una casella combinata che utilizza il negozio di riferimento, posso configurarlo in questo modo:

{ 
    xtype: 'combobox', 
    allowBlank: false, 
    forceSelection: true, 
    store: Ext.getStore('SomeReferenceStore'), 
    queryMode: 'local', // this makes sure the store doesn't reload 
    valueField: 'id', 
    displayField: 'name' 
} 

Per dare un esempio di due negozi che entrambe rientrano nella prima categoria, con uno che dipende da un altro:

In una delle mie applicazioni che hanno un numero dinamica dei permessi degli utenti, quando un utente accede in app ho bisogno per andare a prendere i vari permessi e modificare il modello User per includere un campo booleano per ciascuna di queste diverse permesso:

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... 

    } 

}); 

Con questo, ogni volta che ho bisogno di un riferimento per l'utente e le autorizzazioni che ha a disposizione ho semplicemente chiamo:

var user = Ext.getStore('CurrentUser').first(); 

A volte la vista sarà anche dipendente da un negozio viene caricata. Per esempio i miei principali voci di menu sono determinate da una tabella del database, in quel caso vorrei includere un onLoad ascoltatore allo stesso modo (all'interno la funzione init del controller):

// create the menu once we know what menu items are available 
me.getMenuStore().on('load', function(store) { 
    me.getViewport().add(Ext.widget('mainpanel'));    
}); 

Il MyApp.store.Menu sé sarebbe configurato con autoLoad: true.

2. Negozi che si applicano a tutte le istanze di una vista

ho creare e caricare questi, proprio come la prima categoria unica li ho messi nello specifico vistastores serie del controllore al posto del "principale" controller stores array.

Quindi è lo stesso concetto di base, alcuni sono autoLoad: true alcuni non lo sono se dipendono dai dati di un altro negozio.

Per quelli che non sono autoLoad: true vengono caricati da qualche parte all'interno della funzione init del controller o come risultato dell'attivazione di alcuni eventi.

3. Negozi che sono legati a una singola vista esempio

Qui posso andare contro il grano MVC, ma non c'è davvero posto migliore per un negozio che si applica a una singola istanza di un guarda poi dentro la vista stessa.

Nella maggior parte dei casi non ho nemmeno messo questi negozi nell'array stores del controller di visualizzazione. Creo e li carico solo all'interno della funzione initComponent della vista. Di conseguenza, quando la vista viene distrutta, non vi è più alcun riferimento al negozio, quindi anche il negozio verrà distrutto. Ciò aiuta a ridurre le risorse per i negozi che potrebbero essere creati molte volte.

Ad esempio, supponiamo di avere un MyApp.view.UnicornWeightGrid che estende uno gridpanel e mostra il peso progressivo di un unicorno nel tempo. Un utente può aprire un UnicornWeightGrid per tutti gli unicorni nel regno per scopi di confronto e di riferimento incrociato. Ci saranno tante diverse istanze dello UnicornWeightStore in quanto vi sono istanze dello UnicornWeightGrid.

La vista potrebbe essere definita in questo modo:

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

Poi ogni volta che vogliamo ottenere un diverso UnicornWeightGrid possiamo semplicemente chiamare:

var grid = Ext.widget('unicornweight', { 
    unicornName: someUnicornNameVariable 
}); 

myTabPanel.add(grid); 

Qualsiasi onLoad ascoltatori ho bisogno sui negozi che sono definiti in una vista, allego anche all'interno della vista. Quindi non ho davvero bisogno di riferimenti altrove.

Con tutto ciò che detto, questo non è affatto l'unico modo per impostare i tuoi negozi.

Ho trovato questo il modo più efficace per gestire gli archivi in ​​modo coerente nella creazione di alcune diverse app "MVC" di ExtJS, ma a volte lo faccio diversamente anche in casi "speciali".

Si dovrebbe tenere presente che "MVC" è un modello di progettazione piuttosto allentato, è definito e implementato in modo diverso in quasi ogni singolo framework che ho usato. Quindi puoi fare praticamente tutto ciò che è meglio per te.

+1

Che risposta straordinaria. Grazie mille! :) Voglio dire che avevo pensieri per conto mio, ma questo è solo molto completo e ben formulato. Perché non posso invertire più volte, comunque? – Mithon

0

È necessario inserire la logica per caricare il negozio all'interno del controller per la griglia che visualizzerà questo negozio. Li ho inseriti nell'handler dell'evento afterrender.

Problemi correlati