2011-10-04 21 views
8

Digamos que tengo un controlador principal, luego mi aplicación tiene un controlador para cada "módulo". Este controlador principal contiene la ventana gráfica, luego un encabezado (con un menú) + un contenedor "centrado", que está vacío al principio.Uso de más de un controlador con ExtJS 4 MVC

Un clic en el menú cambiará el módulo/controlador actual y la vista adhoc (que pertenece a este controlador) se mostrará en el contenedor centrado.

Creo que es un escenario muy simple, pero extrañamente no encontré el modo correcto para hacerlo. ¿Algunas ideas? ¡Muchas gracias!

Respuesta

9

Esto es lo que hago: tengo una barra de herramientas en la parte superior, una navegación a la izquierda y la ubicación central es el área de trabajo (básicamente un panel de pestañas) como usted mencionó. Vamos a tomar cada parte fo la aplicación y explain.First, aquí es cómo mi vista parezca:

Ext.define('App.view.Viewport',{ 
    extend: 'Ext.container.Viewport', 
    layout: 'border', 
    requires: [ 
     'App.view.menu.NavigationPane', 
     'App.view.CenterPane',   
     'App.view.menu.Toolbar' 
    ], 
    initComponent: function() { 
     Ext.apply(this, { 
      items: [{ 
       region: 'north', 
       xtype: 'panel',     
       height: 24,          
       tbar: Ext.create('App.view.menu.Toolbar')          
      },{ 
       title: 'Navigation Pane', 
       region: 'west', 
       width: 200, 
       layout: 'fit', 
       collapsible: true, 
       collapsed: true, 
       items: Ext.create('App.view.menu.NavigationPane')          
      },{ 
       region: 'center',            
       xtype: 'centerpane'          
      }]  
     }); 

     this.callParent(arguments); 
    } 
}); 

Se puede ver que tengo una barra de herramientas (App.view.menu.Toolbar) con menú y navegación de la izquierda (App.view.menu.NavigationPane). Estos dos componentes forman mi menú principal o puerta de enlace a otros módulos. Los usuarios seleccionan el elemento del menú y las vistas apropiadas del módulo (como formulario, cuadrícula, tablas, etc.) se cargan en el 'panel central'. El panel central no es más que una clase derivada de Ext.tab.Panel.

Como usted dijo, tengo un controlador principal que maneja todas las solicitudes desde la barra de herramientas y el panel de navegación. Manejó solo la barra de herramientas y las acciones de clic del panel de navegación. Aquí está mi AppController:

Ext.define('CRM.controller.AppController',{ 
    extend: 'Ext.app.Controller',  
    init: function() { 

     this.control({ 

      'apptoolbar button[action="actionA"]' : { 
        click : function(butt,evt) { 
          this.application.getController('Controller1').displayList(); 
        } 
      }, 
      . 
      . // Add all your toolbar actions & navigation pane's actions... 
      .   
      'apptoolbar button[action="actionB"]' : { 
        click : function(butt,evt) { 
          this.application.getController('Controller2').NewRequest(); 
        } 
      } 
     });  
    } 
}); 

Mire uno de los controladores de mi botón. Te echo mano del controlador a través de la propiedad 'aplicación':

this.application.getController('Controller2').NewRequest(); 

Con la ayuda del método de getController, consigo la instancia del controlador y luego llamar a cualquier método dentro de mi controlador. Ahora vamos a echar un vistazo al esqueleto de controlador de mi módulo: controlador

Ext.define('CRM.controller.Controller2',{ 
    extend: 'Ext.app.Controller',  
    refs: [   
     {ref:'cp',selector: 'centerpane'}, // reference to the center pane 
     // other references for the controller 
    ], 
    views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'], 
    init: function() { 

     this.control({ 

      'newform button[action="save"]' : { 
       // Do save action for new item 
      }, 
      'editform button[action="save"]' : { 
       // update the record... 
      }, 
      'c2gridx click' : { 
       // oh! an item was click in grid view 
      } 
     });  
    }, 
    NewRequest: function() { 
     var view = Ext.widget('newform'); 
     var cp = this.getCp();  // Get hold of the center pane... 
     cp.add(view); 
     cp.setActiveTab(view); 
    }, 
    displayList: function() { 
     // Create grid view and display... 
    } 
}); 

Mi de módulo tiene solamente las acciones relacionadas con el módulo (rejilla de un módulo, formas, etc.). Esto debería ayudarlo a comenzar a rodar en la dirección correcta.

+0

Gracias por la buena explicación, sin embargo, sigue siendo un problema para mí. Por favor revisa el comentario que di a la respuesta anterior (techknowfreak). – TigrouMeow

+0

lo siento, no te conseguí. ¿Dónde está el llamado controlador hijo conociendo el controlador padre? ¿Puedes elaborar? No hay interacción iniciada desde los controladores del módulo hasta el controlador principal en el código anterior. ¿derecho? o entiendo que está equivocado ... :) –

+1

Lo sentimos, el controlador hijo no sabe acerca de _parent view_ ('centerpane' aquí).Me gustaría que los módulos (grupo de controladores + vistas) puedan ser independientes. – TigrouMeow

1

En el controlador principal añaden controlador de niño en el controlador de eventos Click del menú

Ext.define('MyAPP.controller.MainController',{ 
... 
    init:function() 
    { 
    this.control({ 
    'menulink': 
    { 
     click:this.populateCenterPanel 
    } 
    }); 
    }, 
    populateCenterPanel:function() 
    { 
    this.getController('ChildController'); 
    } 
}); 

En función de lanzamiento añadir oyente al controlador añadir evento como este -

Ext.application({ 
... 
    launch:function(){ 
    this.controllers.addListener('add',this.newControllerAdded,this); 
    }, 

    newControllerAdded:function(idx, ctrlr, token){ 
    ctrlr.init(); 
    } 
}); 

código Ahora ponga para incrustar dinámicamente vistas en la ventana gráfica en el método init de ChildController.

Ext.define('MyAPP.controller.ChildController',{ 
... 
    refs: [ 
    {ref:'displayPanel',selector:'panel[itemId=EmbedHere]'} 
    ] 
    init:function(){ 
    var panel=this.getDisplayPanel(); 
    panel.removeAll(); 
    panel.add({ 
     xtype:'mycustomview', 
     flex:1, 
     autoHeight:true, 
     ... 
    }); 
    } 
}); 

HTH :)

+0

Esa es la idea que también tuve, el problema es que me gustaría evitar que los controladores hijos sepan cuál es su padre. Es un poco como un bebé que elige a sus padres antes de nacer, ¿verdad? : p – TigrouMeow

+0

luego use eventos de la aplicación ... permita que el controlador principal active el evento de la aplicación cuando se hace clic en el menú y el controlador del niño lo maneja. – techknowfreak

+1

Eso es lo que hago ahora, y paso la identificación del 'contenedor principal' al controlador, de modo que pueda usar 'this.control' y 'refs' correctamente. Todavía creo que son muchos pequeños trucos, me encantaría que todo eso se gestione de forma dinámica por el framework :( – TigrouMeow

Cuestiones relacionadas