2012-03-02 15 views
9

Costruisco la mia applicazione ExtJS 4 seguendo la struttura MVC. Voglio creare una griglia estensibile MyGrid con alcune funzionalità che posso riutilizzare più volte. Quindi, immagino, dovrebbe avere un proprio controller che è anche esteso, in modo che la funzionalità sia ereditata. Come è fatto correttamente?Estendere il controller nell'applicazione MVC ExtJS 4

Nel codice seguente illustro come estendo il controller MyGrid con MyExtendedGrid. Mi rendo conto che sto ignorando la funzione init nel controller MyGrid, in modo che non venga mai chiamata. Il problema è stato risolto semplicemente chiamando il "super" init in MyGrid da MyExtendedGrid init, o unire il controllo oggetti? È questo il modo giusto per farlo nello spirito MVC? Se é cosi, come?

regolatore/MyGrid.js:

Ext.define('App.controller.MyGrid', { 
    extend: 'Ext.app.Controller', 
    refs: [ 
     { 
      ref: 'myGridView', 
      selector: 'mygrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'mygrid textfield[name=searchField]': { 
       change: function() { 
        var view = me.getMyGridView(); 
        // Do something with view 
       } 
      } 
     }); 
    } 
}); 

regolatore/MyExtendedGrid.js:

Ext.define('App.controller.MyExtendedGrid', { 
    extend: 'App.controller.MyGrid', 
    views: [ 
     'grids.MyExtendedGrid'], 
    refs: [ 
     { 
      ref: 'myExtendedGridView', 
      selector: 'myextendedgrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'myextendedgrid': { 
       // Some control code 
       // Using getMyExtendedGridView() 
      } 
     }); 
    } 
}); 

vista/griglie/MyGrid.js:

Ext.define('App.view.grids.MyGrid', { 
    extend: 'Ext.grid.Panel', 
    alias : 'widget.mygrid', 
    requires: [ 
    ], 
    store: '', // Not defined here 
    columns: [ ], // Not defined here 

    initComponent: function() { 
     var me = this; 
     me.tbar = [ 
      'Search', 
      { 
       xtype: 'textfield', 
       name: 'searchField', 
       hideLabel: true, 
       width: 150 
      } 
     ]; 
     me.callParent(arguments); 
    } 
}); 

vista/griglie/MyExtendedGrid .js:

Ext.define('App.view.grids.MyExtendedGrid', { 
    extend: 'App.view.grids.MyGrid', 
    alias : 'widget.myextendedgrid', 
    store: 'MyStore', 
    columns: [ 
     // ... 
    ], 

    initComponent: function() { 
     var me = this; 
     me.bbar = [ 
      //... 
     ]; 
     me.callParent(arguments); 
    } 
}); 

risposta

2

Ok, dopo un po 'di riflessione ho deciso sulla seguente soluzione, che ha il vantaggio che mygrid non ha bisogno di sapere su myextendedgrid.

Estendo il mio gridview come nella domanda.

Ho assegnato alla griglia di base il proprio controller per eseguire le funzionalità comuni, ad esempio deleteButton.setDisable(false) quando qualcosa è selezionato nella griglia.

Successivamente, mi ricordo che l'utilizzo di refs:[ (ad esempio con selector: 'mygrid') indirizza ambiguamente a entrambe le istanze della classe di base tutte le istanze estese.Quando si utilizza me.control({ sono invece ottengo rete rilevante attraversando dall'elemento attivato utilizzando up:

me.control({ 
    'mygrid textfield[name=searchField]': { 
     change: function(searchfield) { 
      var grid=searchfield.up('mygrid'); // (mygrid or myextendedgrid!) 
      // Do something with view 
     } 
    } 
... 

La griglia estesa do un proprio controllore e qui potrebbe utilizzare refs. Non estendo il controller dalla classe MyGrid (ma piuttosto da 'Ext.app.Controller'), a meno che non desideri utilizzare funzioni o variabili dal controller MyGrid. Tutti i controllori vengono avviati da app.js utilizzando:

Ext.application({ 
    controllers: [ 
     'MyGrid' 
     'MyExtendedGrid', 
    ], 
... 

Al fine di ottenere la griglia quando le righe sono selezionate nella griglia, ho memorizzato la griglia nel modello selezione come di seguito:

In controllore/MyGrid.js:

me.control({ 
    'mygrid': { 
     afterrender: function(grid) { 
      var selModel=grid.getSelectionModel(); 
      selModel.myGrid=grid; 
     }, 
     selectionchange: function(selModel, selected, eOpts) { 
      var grid=selModel.theLookupGrid; 
      // Do something with view 
     } 
... 
1

In realtà è un po 'più complicato ...

Ecco quello che abbiamo fatto nella nostra applicazione (abbiamo situazione esattamente lo stesso - una sorta di controller di base, che viene riutilizzato in molti luoghi diversi)

  1. Mantieni la funzione init nel controller di base.

  2. Definire il metodo di base comune in questo controller di base (come gridRendered - dove è necessario eseguire qualsiasi operazione per tutti i controller per tutto il tempo).

  3. Iscriviti agli eventi in tutti i controller figlio ma sottoscrivi gli eventi utilizzando i metodi del controller di base. Altrimenti non funzionerà altrimenti: il controller di base non dispone di riferimenti adeguati per la corretta iscrizione agli eventi.

Posso inserire coppie di frammenti di codice sorgente, ma penso che sia piuttosto semplice.

+0

Grazie, mi hai dato qualche ispirazione .. – Louis

+0

@sha vorrei davvero amarla se si desidera inviare un frammento di codice o due. –

+0

@LeviHackwith: nessun problema. facciamolo in una domanda separata, quindi non confondiamo questo. Vuoi postare una nuova domanda? – sha

Problemi correlati