You are on page 1of 11

Arquitectura Mvc Ext JS

Ext Js, es un framework de Java Script que permite desarrollar potentes aplicaciones del lado del servidor. Ext js esta basado en Java Script orientado a objetos, en consecuencia desde ahora en adelante cada componente que encontremos ser para nosotros un objeto. Entre funcionalidades que mas destacan podemos mencionar, la creacin de formularios,

validaciones de forma sencilla y rpida, creacin de grficos estadsticos con buena presentacin para el usuario, listas llamadas Grillas con paginacin, ordenamiento y filtro, Combos con autocomplete, adems de las funciones Ajax, que permiten obtener y manipular repuestas del servidor en formatos JSON y XML. Cabe mencionar que as como todo en la vida, nada es perfecto, este framework tiene sus inconvenientes. Durante la experiencia que llevamos utilizando Ext Js, nos hemos encontrado con un conjunto de inconvenientes, como por ejemplo duplicidad de cdigo, enormes lneas de cdigo debido a que cada componente es un objeto Java Script, interaccin con elementos HTML, ejecucin de eventos, por ejemplo no se puede llamar a un objeto si antes no se termino de renderizar, es decir no se termino de pintar en HTML mediante DOM. Este conjunto de problemas conllevan casi siempre a un resultado final, el desorden del cdigo volvindolo casi inmantenible. Al parecer los creadores de Ext Js, el tal Ed Spencer y su equipo, se dieron cuenta de dicho problema y crearon la Arquitectura mvc para Ext Js, donde se ofrece reducir los problemas antes mencionados. A mi parecer es una solucin muy interesante por que realmente si se ordena el cdigo adems de manejar correctamente los eventos de los objetos.

Ejecutando el Ejemplo
Para el desarrollo del ejemplo prc tico utilizaremos Spring 3 c omo manejador de transacc iones con el servidor, y Mysql como motor de base de datos.Hemos c reado una tabla Usuario a la c ual realizaremos un CRUD completo c on la arquitec tura mvc de Ext JS.

Las aplic ac iones Ext JS 4 siguen una estruc tura de direc torio unificado que es el mismo para c ada aplicac in, ahora c rearemos una estructura de direc torios como se muestra en la siguiente figura

Debemos agregar las referenc ias de Ext casousuario.jsp

y nuestra aplic ac in a nuestra pagina en este

Y debe quedar de la Siguiente manera 1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2. <html> 3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 4. <head> 5. <meta content=""> 6. <title>Usuario</title> 7. 8. <!-- ExtJS --> 9. 10. 11. 13. 14. <!-- LENGUAJE --> 15. <script type="text/javascript" src="ext4/locale/ext-lang-es.js"></script> 16. <!-- FIN LENGUAJE --> 17. </head> 18. <body> 19. 20. </body> 21. </html> <link rel="stylesheet" type="text/css" href="ext4/resources/css/ext-all.css" /> <script type="text/javascript" src="ext4/bootstrap.js"></script> <script type="text/javascript" src="app/app.js"></script>

12. <!-- ExtJS -->

Creacin de la Aplicacin
Nos dirigimos a app.js y escribimos estas lneas de cdigo 1. Ext.Loader.setConfig({ 2. 3. }); 4. 5. Ext.application({ 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. })//Funcion con la que empieza nuestra aplicacion } title:' Mvc Usuario Demo - CRUD' ,frame:true ,style:'margin:20px 200px 20px 200px' ,bodyStyle:'padding:10px' ,renderTo:Ext.getBody()// se pinta en el body del jsp }) //Crearemos un panel q contendra nuestros elementos Ext.create('Ext.panel.Panel',{ name:'AD'//Nombre de Nuestra Aplicacion ,appFolder:'app'//Ruta donde se encuentra la estructura de nuestra aplicacion ,launch:function(){ enabled: true

22. }); El resultado debe ser el siguiente

Observacin: Como habrn notado, a nuestra aplicac in le asignamos el atributo name c on el valor AD, (Aplic ac in Demo), el nombre es lo de menos, pueden poner la abreviatura que deseen, pero que represente lgicamente la desc ripc in del negocio. Es importante apuntar que dicho nombre AD, indic ara el prefijo para nuestros futuros componentes, es decir por ejemplo si vamos a crear un c ontroller, la definicin ser AD.controller.UsuarioController, para un modelo,

AD.model.UsuarioModel, etc .

Creacin del Controller


Los controladores son el engranaje de nuestra aplic ac in. Son los encargados de que todo funcione. Los controladores son c omo el pegamento que une todas las partes de la aplic ac in entre si Nos dirigiremos a UsuarioController.js y pegamos estas lineas de c odigo

1. Ext.define('AD.controller.UsuarioController', { 2. 3. 4. 5. 6. }); } extend: 'Ext.app.Controller', init: function() { console.log('Controller agregado satisfactoriamente');

Posteriormente

debemos

asoc iar

nuestra

aplic ac ion

(app.js),

el

controladorUsuarioController.js , de esta manera:

1. Ext.Loader.setConfig({ 2. 3. }); 4. 5. Ext.application({ 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. })//Funcion con la que empieza nuestra aplicacion } title:' Mvc Usuario Demo - CRUD' ,frame:true ,style:'margin:20px 200px 20px 200px' ,bodyStyle:'padding:10px' ,renderTo:Ext.getBody()// se pinta en el body del jsp }) //Crearemos un panel q contendra nuestros elementos Ext.create('Ext.panel.Panel',{ name:'AD'//Nombre de Nuestra Aplicacion ,appFolder:'app'//Ruta donde se encuentra la estructura de nuestra aplicacion ,controllers : ['UsuarioController'] //Puede ser mas de Un controlador ,launch:function(){ enabled: true

23. });

El resultado ser el siguiente

Como explic amos anteriormente, el c ontroller es el elemento de engranaje de nuestra aplic ac in se enc arga de unir y despac har nuestros eventos. Para probar lo dicho escribiremos unas lneas de cdigo en nuestro controlador. Primero agregaremos un atributo a nuestro panel c ontenedor que se enc uentra en nuestra aplicac in app.js, id:PanelUsuario.

1. ... 2. 3. 4. 5. title:' Mvc Usuario Demo - CRUD' ,frame:true Ext.create('Ext.panel.Panel',{

6. ,id: 'PanelUsuario ' 7. 8. 9. 10. ,style:'margin:20px 200px 20px 200px' ,bodyStyle:'padding:10px' ,renderTo:Ext.getBody()

11.

})

12. ... Ahora agregaremos estas lneas de c digo a nuestro c ontroller UsuarioController.js 1. Ext.define('AD.controller.UsuarioController', { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. }}); console.log('Panel usuario renderizado'); console.log('Panel usuario - this'); console.log(panel); console.log('Panel usuario - event'); console.log(e); } , renderPanelUsuario:function(panel,e){ ); } } render:this.renderPanelUsuario this.control( { 'panel#PanelUsuario':{ extend: 'Ext.app.Controller', init: function() {

El resultado ser el siguiente

La func in this.control agrega, eventos de c ontrol a los c omponentes que deseemos, en nuestro ejemplo esc ribimos 'panel#PanelUsuario', esto quiere dec ir que de todos los paneles de nuestra aplicac in, el que posea el id PanelUsuario, agregar en el evento render, la func in

renderPanelUsuario, esta func in tiene como parmetros ya establec idos, siendo el primero el objeto panel c on id PanelUsuario.

Definiendo nuestras Vistas


Las vistas son c omponentes c reados, heredados de otros componentes de Ext. Una vista representa cualquier interac cin con el usuario, podra ser por ejemplo, una grilla, formularios, panels, c harts, etc .

Creando Nuestra Grilla


Vamos a renombrar el js, UsuarioPanel.js por UsuarioGridPanel.js

Ahora escribiremos estas lineas de c digo 1. Ext.define('AD.view.usuario.UsuarioGridPanel' ,{ 2. extend: 'Ext.grid.Panel',

3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. });

alias : 'widget.gridUsuario, initComponent: function() { this.store = { fields: ['nombres', 'email','login','idusuario','celular'], data : [ {idusuario: '1', {idusuario: '2', ] }; this.columns = [ {header: 'Cod.', dataIndex: 'idusuario', width:80}, {header: 'Login', dataIndex: 'login', width:100}, {header: 'Nombres', dataIndex: 'nombres', flex: 1}, {header: 'Login', dataIndex: 'login', width:130}, {header: 'Celular', dataIndex: 'celular', width:130}, {header: 'Email', dataIndex: 'email', flex: 1} ]; this.callParent(arguments); } nombres: 'Arturo Sanchez',login:'asanchez', celular: '969007452',email:'asanchez@gmail.com'} nombres: 'Manuel Sanchez',login:'msanchez', celular: '994478913',email:'msanchez@gmail.com'}

Expliquemos que signific a las lneas arriba esc ritas: Ext.define('AD.view.usuario.UsuarioGridPanel') Estamos definiendo una vista, y le indic amos la ruta donde se enc uentra el JS que genera la vista. extend: 'Ext.grid.Panel' Le estamos diciendo que es un objeto heredado de un Grid Panel. alias : 'widget.gridUsuario' Es el nombre de nuestra vista, es el nombre con el que lo invocaremos. initComponent Es la funcin que inic ializa los c omponentes de la grilla Por el momento c argaremos nuestra grilla de forma esttica, mas adelante obtendremos los datos desde la base de datos.

Transacciones con Base de datos


Hasta el momento, si todo ha salido bien, solo hemos ejec utado componentes sin c onectarnos a la base de datos. Para poder c onsumir los registros de nuestra base de datos y poder manipularlos vamos a realizar algunos c ambios en la estruc tura de muestras vistas, as c omo la creac in de stores y models que nos darn el soporte nec esario para ejec utar transac ciones a la base de datos. Vamos a agregar unos estilos a la pgina usuario.jsp

1. <style> 2. 3. 4. 5. 6. 7. 8. 9. 10. } } .eliminar { background-image:url(icons/fam/user_delete.gif) !important; } .editar { background-image:url(icons/fam/user_edit.png) !important; .add { background-image:url(icons/fam/user_add.gif) !important;

11. </style>

Creando Nuestro Model


El Model es el componente que representa la entidad del negoc io a la c ual vamos a abstraer, en este caso es la entidad Usuario. Para esto nos Dirigiremos a UsuarioModel.js y esc ribiremos estas lneas de c digo.

1. Ext.define('AD.model.UsuarioModel', { 2. 3. 4. }); extend: 'Ext.data.Model', fields: ['nombres', 'email','login','idusuario','celular']

Creando Nuestro Store


Un Store (almac n), c omo su propio nombre lo desc ribe, es un almac n de datos, que ser consumido por algn c omponente que lo nec esite, c omo por ejemplo en nuestro caso una grilla, pero no nec esariamente tiene que ser as, tambin podra ser c onsumido por un c ombobox, un grfic o estadstic o o simplemente como un Array de objetos de nuestra entidad de negocio. Antes de empezar a c rear nuestro Store de datos, es nec esario explic ar algunos puntos de la definic in de los stores. El Store puede ser abastec ido de diferentes maneras, estas pueden ser: Un Array de Objetos de Java Sc ript Json Xml Jsonp Otros En nuestro ejemplo cargaremos el Store mediante un Json, dic ho Json ser se generar mediante una peticin Ajax a nuestro servidor, el servidor se enc argar de generar una respuesta c on el respec tivo formato, no profundizaremos en la generac in de los mtodos en java que forman nuestro json, pues no es el fin de este documento, sin embargo la creac in de los mtodos estn registrados en el video tutorial, puedes consultar dic ho video para mas informac in. La Respuesta de nuestro servidor en el formato Json debe ser el Siguiente:

1. { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. "data" : [{ "idusuario" : 1, "password" : "123", "email" : "asanchez.sys@gmail.com", "celular" : "969007452", "login" : "arturo.sanchez", "nombres" : "Arturo Sanchez Soto" }, { "idusuario" : 2, "password" : null, "email" : "msanchez@gmail.com", "celular" : "994478913", "login" : "msanchez", "nombres" : "Manuel Sanchez Soto" }, { "idusuario" : 3, "password" : null, "email" : "delina.soto@gmail.com", "celular" : "915265614", "login" : "dsoto", "nombres" : "Delina Soto Mendoza" }, { "idusuario" : 4, "password" : null, "email" : "xmara@gmail.com", "celular" : "948984787", "login" : "xmara", "nombres" : "Xiomara Morales Asalde" }], "success" : true

32. } Como pueden observar c ada objeto de nuestro Json, tiene c orrespondencia c on la definic in de los fields de nuestro model.

Ahora teniendo listo nuestro Json vamos a c rear nuestro Store, Esc ribamos estas lneas de c digo en UsuarioStore.js

1. Ext.define('AD.store.UsuarioStore', { 2. extend: 'Ext.data.Store',

3. 4. 5. 6. 7. {

model: 'AD.model.UsuarioModel', autoLoad:true, remoteSort:true, proxy :

8. type: 'ajax', 9. actionMethods:'POST', 10. 11. 12. 13. 14. 15. 16. 17. } }); url : 'listarusuario.app', reader : { type: 'json', root : 'data' }, simpleSortMode : true

Como vemos el modelo al que hac e referencia apunta al Model UsuarioModel, este componente hereda de la c lase data.Store , y le hemos atribuido c aractersticas c omo autoLoad:true , para que c argue el Json al inic iar, remoteSort:true , para que ordene desde el servidor y no de modo local, y la c aracterstica mas importante que es el proxy. El Proxy es el elemento de c onfigurac in de llamado del Json, el atributo type:ajax, indic a que la petic in ser

mediante Ajax, actionMethods:POST, la petic in al servidor se har mediante el mtodo post, el atributo url: 'listarusuario.app', es el url que proporc iona el json, el atributo reader en su propiedad type , indica que el formato c on el que rec ibe la petic in es json, y la cabec era que indica desde donde empieza nuestros datos es dec ir el nombre del objeto que contienen los datos, le c orresponde al atributo root. Seguidamente le indic aremos a nuestro controlador, que puede utilizar, el model UsuarioModel y el Store UsuarioStore, para esto

modific aremos UsuarioController.js , y le aumentamos estos atributos

1. ... 2. stores : ['UsuarioStore'], 3. models : ['UsuarioModel'], 4. ... Ahora modifiquemos UsuarioGrid.js

1. Ext.define('AD.view.usuario.UsuarioGridPanel' ,{ 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. this.columns = [ {header: 'Cod.', dataIndex: 'idusuario', width:80}, {header: 'Login', dataIndex: 'login', width:100}, }]; }] this.dockedItems = [ { xtype: 'toolbar', items: [{ text:'Nuevo', tooltip:'Agregar Nuevo Usuario', id:'btnNewUser', action:'new', iconCls:'add' }, '-', { text:'Modificar', tooltip:'Modificar Usuario', id:'btnEditUser', iconCls:'editar', action:'editar', disabled:true },'-',{ text:'Eliminar', id:'btnRemoveUser', tooltip:'Eliminar Usuario', iconCls:'eliminar', action:'eliminar', disabled:true this.store = 'UsuarioStore'; extend: 'Ext.grid.Panel', alias : 'widget.gridUsuario', initComponent: function() {

36. 37. 38. 39. 40. 41. 42. 43. 44. }); } ];

{header: 'Nombres',

dataIndex: 'nombres',

flex: 1},

{header: 'Login', dataIndex: 'login', width:130}, {header: 'Celular', dataIndex: 'celular', width:130}, {header: 'Email', dataIndex: 'email', flex: 1}

this.callParent(arguments);

Ntese que el atributo this.store ahora apunta a UsuarioStore El resultado se debera parec er a la imagen siguiente:

Edicin de Usuario
Para c ompletar nuestro CRUD, vamos a agregar la func ionalidad de crear nuevos usuarios y ac tualizarlos. Para esto crearemos una vista tipo window, donde se alojar un formulario de registro de usuarios. El js que c ontiene el c digo de nuestra vista se llamar UsuarioWindow.js.

1. Ext.define('AD.view.usuario.UsuarioWindow', { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. }); Observacin: Ntese que se c re una variable llamada win que contiene todo el objeto window (this), este artific io lo utilizaremos, para enviarlos c omo atributo en los botones, para poder manipular nuestra vista. Ahora agregaremos a nuestro c ontrolador Nuestra Vista UsuarioWindow. } ]; this.callParent(arguments); ]; this.buttons = [ {text: 'Grabar', action: 'grabar', win:win}, {text: 'Cancelar',scope: this,: this.close, win:win} } ] extend: 'Ext.window.Window', alias : 'widget.usuarioEdit', title : 'Edicion de Usuario', layout: 'fit', initComponent: function() { var win=this; this.border=false; this.width=400; this.items = [ { xtype: 'form', frame:false, style:'border:0px;', bodyStyle:'padding:10px', border:false, id:'formUser', items: [ {xtype: 'textfield',: 'idusuario', fieldLabel: 'C&oacute;digo',hidden:true, width:200, labelWidth:60}, {xtype: 'textfield', name : 'nombres', fieldLabel: 'Nombres', width:350, labelWidth:60}, {xtype: 'textfield', name : 'login', fieldLabel: 'Login', width:350, labelWidth:60}, {xtype: 'textfield', name : 'email', fieldLabel: 'Email', width:350, labelWidth:60}, {xtype: 'textfield', name : 'celular', fieldLabel: 'Celular',width:350, labelWidth:60}

1. ... 2. views : ['usuario.UsuarioGridPanel', 'usuario.UsuarioWindow'] 3. ...

Empaquetando nuestras funciones como un servicio


Hemos agregado una c apa ms a nuestra aplicac in, que c onsiste en separar las func iones de

lgica de negoc io y as tener mas limpio nuestro c digo. Este c onjunto de func ionalidades sern empaquetadas en una clase Js llamada Usuario.Service, que se encuentra en el archivo UsuarioService.js, c uyo cdigo fuente es el siguiente:

1. Ext.ns('Usuario.Service'); 2. 3. Usuario.Service = { 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. Ext.getCmp('btnEditUser').setDisabled(true); Ext.getCmp('btnRemoveUser').setDisabled(true); }, disableEdit : function() { Ext.getCmp('btnEditUser').setDisabled(false); Ext.getCmp('btnRemoveUser').setDisabled(false); }, enableEdit : function() { win.setTitle(title); win.show(); } win.down('form').loadRecord(record); var record = grid.getSelectionModel().getSelection()[0]; if (grid) { var win = Ext.widget('usuarioEdit'); , openWinUsuario : function(title, grid) { } } }); Ext.Ajax.request({ url : 'eliminarusuario.app', method : 'POST', success : function(response, opts) { var grid = Ext.getCmp('gridUsuario'); grid.store.load(); }, params : { idUsuario : idUsuario }, failure : function(res, opt) { alert("Error"); }, eliminarUsuario : function(idUsuario, win) { } }) }, failure : function(f, a) { alert('error') form.submit({ method : 'POST', url : 'actualizarusuario.app', success : function(f, a) { form.reset(); var grid = Ext.getCmp('gridUsuario'); grid.store.load(); console.log(win) win.close(); actualizarUsuario : function(form, win) {

70. 71. 72. 73. } }

Como pueden observar en esta c lase se enc uentran los mtodos que darn func ionalidad a nuestro CRUD. Ahora para terminar nuestro ejemplo prc tic o, ac oplaremos nuestro Controlador para consumir los mtodos de usuario.servicie.

1. Ext.define('AD.controller.UsuarioController', { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. actualizarUsuario : function(boton) { , , selectRecord : function(grid, record) { Usuario.Service.enableEdit(); } } var grid = Ext.getCmp('gridUsuario'); Usuario.Service.openWinUsuario('Editar Usuario', grid); }, editarUsuario : function(grid, record) { Usuario.Service.openWinUsuario('Nuevo Usuario') }, newUsuario : function(boton, e) { }, renderPanelUsuario : function(panel, e) { ); } } click : this.actualizarUsuario , 'usuarioEdit button[action=grabar]' : { }, 'gridUsuario button[action=new]' : { click : this.newUsuario }, 'gridUsuario' : { select : this.selectRecord, afterrender : this.afterRenderGrid }, 'gridUsuario button[action=editar]' : { click : this.editarUsuario }, 'gridUsuario button[action=eliminar]' : { click : this.eliminarUsuario } render : this.renderPanelUsuario this.control({ 'panel#PanelUsuario' : { extend : 'Ext.app.Controller', views : ['usuario.UsuarioGridPanel', 'usuario.UsuarioWindow'], stores : ['UsuarioStore'], models : ['UsuarioModel'], init : function() {

64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83.

Usuario.Service.actualizarUsuario(Ext.getCmp('formUser') .getForm(), boton.win);

}, afterRenderGrid : function(grid) { grid.store.addListener('load', function() { Usuario.Service.disableEdit(); });

}, eliminarUsuario : function(boton) { var grid = Ext.getCmp('gridUsuario'); var record = grid.getSelectionModel().getSelection()[0]; Usuario.Service.eliminarUsuario(record.data.idusuario); } });

El c ontroller c omo habamos dicho solo se encargar de despac har las ac ciones de ac uerdo a un determinado evento, y la lgica ser implementada en un nuestro servicio usuario.servic e

Video Tutorial

You might also like