2012-03-02 14 views
9

Construyendo mi aplicación ExtJS 4 siguiendo la estructura MVC. Quiero hacer una grilla extensible MyGrid con alguna funcionalidad que pueda reutilizar varias veces. Por lo tanto, supongo que debería tener su propio controlador, que también se extiende, de modo que la funcionalidad se hereda. ¿Cómo se hace esto correctamente?Controlador de extensión en la aplicación ExtJS 4 MVC

En el siguiente código, se ilustra cómo extiendo el controlador MyGrid con MyExtendedGrid. Me doy cuenta de que estoy sobreescribiendo la función init en el controlador MyGrid, para que nunca se llame. ¿El problema simplemente se resuelve llamando a la "super" init en MyGrid desde MyExtendedGrid init, o combine los objetos de control ? ¿Es esa la manera correcta de hacer esto en el espíritu de MVC? ¿Si es así, cómo?

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

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

Ver/rejillas/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); 
    } 
}); 

Ver/rejillas/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); 
    } 
}); 

Respuesta

2

Bien, después de pensar un poco decidí en la siguiente solución, que tiene la ventaja de que mygrid no necesita saber acerca de myextendedgrid.

Extiendo mi gridview como en la pregunta.

He dado a la grilla base su propio controlador para realizar funciones comunes, por ejemplo deleteButton.setDisable(false) cuando se selecciona algo en la grilla.

A continuación, me recuerdo a mí mismo que usar refs:[ (por ejemplo, con selector: 'mygrid') señalaría ambiguamente a ambas instancias de la clase base cualquier instancia extendida.Al utilizar me.control({ que en lugar de obtener la cuadrícula correspondiente por la que atraviesa desde el elemento que se activa con up:

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

La rejilla extendida que dan su propio controlador y aquí podría utilizar refs. No extiendo el controlador desde la clase MyGrid (sino desde 'Ext.app.Controller'), a menos que desee utilizar funciones o variables del controlador MyGrid. Todos los controladores se inician desde app.js usando:

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

el fin de obtener la cuadrícula cuando las filas se seleccionan en la cuadrícula, que almacena la rejilla en el modelo de selección como a continuación:

En controlador/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

En realidad es un poco más complicado ...

Esto es lo que hicimos en nuestra aplicación (que tenemos exactamente la misma situación - una especie de controlador de base, que se reutiliza en muchos lugares diferentes)

  1. Mantener la función init en el controlador base.

  2. Defina el método base común en este controlador base (como gridRendered, donde necesita hacer algo para todos los controladores todo el tiempo).

  3. Suscríbete a los eventos en todos los controladores secundarios pero suscríbete eventos usando métodos de controlador base. No funcionará de lo contrario: el controlador base no tiene las referencias adecuadas para suscribirse correctamente a los eventos.

Puedo publicar un par de fragmentos de código fuente, pero creo que es bastante sencillo.

+0

Gracias, que me dieron un poco de inspiración .. – Louis

+0

@sha De hecho, me encantaría que usted publicar un fragmento de código o dos. –

+0

@LeviHackwith: no hay problema. hagamos esto en una pregunta separada para no confundir esta. ¿Quieres publicar una nueva pregunta? – sha

Cuestiones relacionadas