Академический Документы
Профессиональный Документы
Культура Документы
mx/2012/01/04/arquitectura-de-la-aplicacion-mvc/
CONTACTO
Las aplicaciones clientes que son grandes siempre han sido muy difíciles de escribir,
difíciles de organizar, más difíciles de mantener. Pueden salirse muy fácil de control
mientras se van agregando funcionalidades o programadores al proyecto. La estructura de
ExtJS 4 viene con una nueva arquitectura de aplicación que no solo organiza tu código,
Cursos presenciales
sino también reduce las líneas que se tienen que escribir. MI PRIMER APLICACIÓN EN EXTJS 4
La arquitectura de una aplicación es el diseño de una estructura adecuada y consistente Estilo de un Botón
para escribir el código de las clases y componentes de la aplicación. Las convenciones que Combo Fecha, validando los días del
se plantean deben pensar en los siguientes importantes beneficios: mes
Ventana Login
Cada aplicación trabaja de la misma manera, entonces solo debemos aprender solo
Tabs Dinamicos
una vez.
Es fácil compartir código entre nuestras aplicaciones debido a que trabajan de la Validación de un EditorGrid antes y
despues de editar
misma manera.
Puedes usar herramientas para construir versiones optimizadas de tu aplicación para Reordenamiento de Arboles en Extjs
su uso en producción. 4.2
misma para todas esas aplicaciones. Curso Desarrollo ágil de una buena
estructura de aplicación
01. <html>
02. <head>
03. <title>Publicaciones
04. <link rel="stylesheet" type="text/css" href="ext4/resources
/css/ext-all.css" />
05. <script type="text/javascript" src="ext4/ext-all-debug.js">
</script>
06. <script type="text/javascript">
07. Ext.Loader.setConfig({
08. enabled: true
09. });
10. </script>
11. <script type="text/javascript" src="app.js"></script>
12. </head>
13. <body></body>
14. </html>
En nuestro ejemplo, ahora crearemos una aplicacion de Publicaciones que nos ayudará a
administrar cuentas de usuario. Primero es necesario definir un nombre global para
nuestra aplicación. Todas las aplicaciones de Ext JS4 deberían utilizar una sola variable
como nombre global, escribiendo todas las otras definiciones de clases dentro de ella,
normalmente son nombres cortos, en este caso utilizaremos JH:
01. Ext.application({
02. name: 'JH',
03.
04. appFolder: 'app',
05.
06. launch: function() {
07. Ext.create('Ext.container.Viewport', {
08. layout: 'fit',
09. items: [
10. {
11. xtype: 'panel',
12. title: 'Usuarios',
13. html : 'Nuestra lista de usuarios se define aqui'
14. }
15. ]
16. });
17. }
18. });
Hay que resaltar algunas cosas aquí. Invocamos a Ext.application para crear una nueva
instancia de la clase Application, pasándole el nombre “JH”. Con esto, automáticamente se
crea una variable global JH para nosotros, y registrando el namespace en Ext.Loader, con
la correspondiente ruta ‘app’ establecido mediante la propiedad de configuración
appFolder. De igual manera proporcionamos el código de la función launch para crear un
Viewport que contiene un único Panel que llena la pantalla completa.
Definiendo un Controlador
Los controladores son la lógica que construye tu aplicación. Todo lo que realmente hacen
es controlar los eventos( usualmente de las vistas) y realizar algunas acciones.
Continuando con nuestro ejemplo, crearemos un controlador con el archivo llamado
app/controller/Usuario.js y escribiendo el siguiente código:
01. Ext.define('JH.controller.Usuario', {
02. extend: 'Ext.app.Controller',
03.
04. init: function() {
05. console.log('Usuario inicializado! Esto
06. pasa antes de que la aplicacion sea lanzada');
07. }
08. });
01. Ext.application({
02. ...
03.
04. controllers: [
05. 'Usuario'
06. ],
07.
08. ...
09. });
La función init es el momento ideal para configurar como el controlador interactúa con la
vista , y usualmente trabaja con otras funciones de otros controladores. La función control
hace fácil el proceso de esperar los eventos en las clases Vista y realiza algunas acciones
con funciones controladoras de esos eventos. Veamos un ejemplo con esto para avisar al
controlador Usuario cuando el panel se ha desplegado:
01. Ext.define('JH.controller.Usuario', {
02. extend: 'Ext.app.Controller',
03.
04. init: function() {
05. console.log('Usuario inicializado! Esto
06. pasa antes de que la aplicacion sea lanzada');
07. this.control({
08. 'viewport > panel': {
09. render: this.onPanelDesplegado
10. }
11. });
12. },
13.
14. onPanelDesplegado: function() {
15. console.log('El panel ha sido desplegado');
16. }
17. });
Actualizamos la función init para utilizar this.control para configurar los listeners de las
vistas en nuestra aplicación. Esta función control utiliza el nuevo motor de
ComponentQuery para obtener referencia rápidamente de los componentes en la página.
En pocas palabras, permite definir un selector como en CSS para encontrar todos los
componentes que coincidan con la regla en la página.
En nuestro ejemplo escribimos ‘viewport > panel’, que se traduce como “encuéntrame
todos los Paneles que sean hijos directos del Viewport”. Inmediatamente proporcionamos
un objeto que mapea el nombre del evento con la función controladora (solo render en
este caso).
Quizás no es la aplicación mas emocionante, pero muestra la organización que debe tener
toda aplicacion. Ahora agregaremos un grid.
Definiendo la Vista
Hasta ahora tenemos la definición de dos archivos app.js y app/controller/Usuario.js.
Ahora que queremos mostrar la lista de usuarios de nuestro sistema, es hora de organizar
la lógica un poquito mejor usando una Vista.
Una vista no es otra cosa que un componente, usualmente definido como subclase de otro
componente de Ext JS. Crearemos un Grid de Usuarios con el nombre app/view/usuarios
/Lista.js y escribimos el siguiente código:
01. Ext.define('JH.view.usuarios.Lista' ,{
02. extend: 'Ext.grid.Panel',
03. alias : 'widget.listausuarios',
04.
05. title : 'Todos los usuarios',
06.
07. initComponent: function() {
08. this.store = {
09. fields: ['nombre', 'email'],
10. data : [
11. {nombre: 'Ed', email: 'ed@sencha.com'},
12. {nombre: 'Tommy', email: 'tommy@sencha.com'}
13. ]
14. };
15.
16. this.columns = [
17. {header: 'Nombre', dataIndex: 'nombre', flex: 1},
18. {header: 'Email', dataIndex: 'email', flex: 1}
19. ];
20.
21. this.callParent(arguments);
22. }
23. });
Nuestra clave Vista no es otra cosa que una clase común y corriente. En este caso
heredamos del componente Grid y le relacionamos un alias que podemos utilizar como un
xtype. También le pasamos las configuraciones de un store y las columnas que debe
utilizar.
01. Ext.define('AM.controller.Users', {
02. extend: 'Ext.app.Controller',
03.
04. views: [
05. ' usuarios.Lista'
06. ],
07.
08. init: ...
09.
10. onPanelRendered: ...
11. });
01. Ext.application({
02. ...
03.
04. launch: function() {
05. Ext.create('Ext.container.Viewport', {
06. layout: 'fit',
07. items: {
08. xtype: ' listausuarios'
09. }
10. });
11. }
12. });
Nótese que agregamos ‘usuarios.Lista’ dentro de un arreglo definiendo las vistas. Esto le
dice a la aplicación cargar automáticamente el archivo , así lo podemos utilizar cuando se
lance. Refrescamos la página ahora y tenemos lo siguiente:
Controlando el grid
Nótese también que nuestra función onPanelDesplegado aun sigue ejecutándose. Esto
debido a que el grid aun coincide con la definición del selector ‘viewport > panel’. Esto es
porque el Grid es una extensión del Panel.
Por el momento, el listener que agregamos seleccionara a cada Panel o subclase del Panel
que son hijos directos del viewport, ahora intercambiemos esta definición directamente
por nuestro nuevo xtype. Con esto esperaremos el evento doble click en las filas del grid
para después editar los datos de un Usuario:
01. Ext.define('JH.controller.Usuario', {
02. extend: 'Ext.app.Controller',
03.
04. views: [
05. 'usuarios.Lista'
06. ],
07.
08. init: function() {
09. console.log('Usuario inicializado! Esto
10. pasa antes de que la aplicacion sea lanzada');
11. this.control({
12. 'listausuarios': {
13. itemdblclick: this.editarUsuario
14. }
15. });
16.
17. },
18.
19. editarUsuario: function(grid, record) {
20. console.log('Doble click en ' + record.get('nombre'));
21. }
22. });
01. Ext.define('JH.view.usuarios.Editar', {
01. Ext.define('JH.controller.Users', {
02. extend: 'Ext.app.Controller',
03.
04. views: [
05. 'usuarios.Lista',
06. 'usuarios.Editar'
07. ],
08.
09. init: ...
10.
11. editUser: function(grid, record) {
12. var view = Ext.widget('listausuarios');
13.
14. view.down('form').loadRecord(record);
15. }
16. });
Dando doble click en una fila de nuestro grid ahora mostrara algo como esto:
01. Ext.define('JH.store.Usuario', {
02. extend: 'Ext.data.Store',
03. fields: ['nombre', 'email'],
04. data: [
05. {nombre: 'Ed', email: 'ed@sencha.com'},
06. {nombre: 'Tommy', email: 'tommy@sencha.com'}
07. ]
08. });
01. Ext.define('JH.controller.Usuario', {
02. extend: 'Ext.app.Controller',
03. stores: [
04. 'Usuario'
05. ],
06. ...
07. });
01. Ext.define('JH.view.userios.Lista' ,{
02. extend: 'Ext.grid.Panel',
03. alias : 'widget.userlist',
04.
05. //y quitamos la definición del Store del usuario en `initComponent`
06. store: 'Usuario',
07.
08. ...
09. });
Además de esto tenemos que definir una instancia de la poderosa clase Ext.data.Model
para tener algunas ventajas al editar los datos. Terminamos las modificaciones creando un
Modelo en el archivo app/model/Usuario.js:
01. Ext.define('JH.model.Usuario', {
02. extend: 'Ext.data.Model',
03. fields: ['nombre', 'email']
04. });
Creando nuestro Modelo , nuevamente hay que actualizar nuestro Store para referenciar a
este recién creado Modelo en lugar de proporcionar los datos directamente, y especificar
al controlador de Usuario hacer también una referencia hacia este Modelo:
03. Ext.define('JH.controller.Usuario', {
04. extend: 'Ext.app.Controller',
05. stores: ['Usuario'],
06. models: ['Usuario'],
07. ...
08. });
09.
10. // y referenciamos al Model en lugar de los datos en duro
11. Ext.define('JH.store.Usuario', {
12. extend: 'Ext.data.Store',
13. model: 'JH.model.Usuario',
14.
15. data: [
16. {nombre: 'Ed', email: 'ed@sencha.com'},
17. {nombre: 'Tommy', email: 'tommy@sencha.com'}
18. ]
19. });
01. Ext.define('JH.controller.Usuario', {
02. init: function() {
03. this.control({
04. 'listausuarios': {
05. itemdblclick: this.editarUsuario
06. },
07. 'editarusuario button[action=guardar]': {
08. click: this.actualizarDatos
09. }
10. }); },
11.
12. actualizarDatos: function(button) {
13. console.log('Boton Guardar presionado');
14. }
15. });
Ahora que nos aseguramos que todo funciona correctamente al presionar el botón
Guardar, escribiremos la lógica para actualizar los datos mediante el método
El evento nos da una referencia de cuando el usuario presiona el botón, pero no solo
queremos eso, también queremos acceder al formulario que contiene los datos dentro de
la misma ventana. Nuevamente, utilizamos el funcionamiento de ComponentQuery,
primero con el método button.up(‘window’) para tener la referencia de la ventana,
después con win.down(‘form’) para llegar al formulario.
01. Ext.define('JH.store.Usuario', {
02. extend: 'Ext.data.Store',
03. model: 'JH.model.Usuario',
04. autoLoad: true,
05.
06. proxy: {
07. type: 'ajax',
08. url: 'data/usuarios.json',
09. reader: {
10. type: 'json',
11. root: 'users',
12. successProperty: 'success'
13. }
14. }
15. });
Con esto, quitamos la propiedad ‘data’ y lo reemplazamos por un proxy. Los Proxis son la
manera de cargar y guardar los datos desde un Store o un Model en Ext JS 4. Hay proxis
por AJAX, JSON-P y HTML5 localStorage entre otros. Aqui utilizamos un proxy de AJAX
simplemente, que carga los datos desde la ruta ‘data/usuarios.json’.
También definimos el reader del Proxy.
Definimos un Json Reader en este caso y especificamos que la raíz de los datos es la
01. {
02. success: true,
03. users: [
04. {id: 1, nombre: 'Ed', email: 'ed@sencha.com'},
05. {id: 2, nombre: 'Tommy', email: 'tommy@sencha.com'}
06. ]
07. }
El único cambio que hacemos en el Store es poner autoLoad en true, que significa que el
Store le pedirá cargar los datos al Proxy inmediatamente al mostrarse el componente. Si
refrescamos la página ahora, veremos la misma vista sin modificaciones, sin embargo los
datos han sido cargados desde una posible base de datos de un servidor Web.
Finalmente, lo último por hacer aquí es enviar los datos nuevamente al servidor una vez
modificados. Para este ejemplo, tenemos los datos en un formato estático JSON cargados
desde un archivo, entonces no veremos ningún cambio en alguna Base de Datos pero al
menos podemos validar que todo está unido correctamente. Primero agregamos en
nuestro proxy una ruta de actualización de los datos para enviar las actualizaciones de la
información:
01. proxy: {
02. type: 'ajax',
03. api: {
04. read: 'data/usuarios.json',
05. update: 'data/updateUsuarios.json'
06. },
07. reader: {
08. type: 'json',
09. root: 'users',
10. successProperty: 'success'
11. }
12. }
Con esto tenemos el ejemplo completo y podemos asegurarnos que todo funciona
correctamente refrescando la página. Editamos la fila y el cliente envía los datos finales al
servidor para ser actualizados en una posible Base de datos.
Nombre Email
Ed ed@sencha.com
Tommy tommy@sencha.com
ExtJS 4
About author:
Joshua es programador Web con mas de 6 años de experiencia, experto en ExtJS,
Sencha y PHP. Ha dedicado su tiempo en compartir sus conocimientos en Talleres,
cursos y conferencias. Ha desarrollo aplicaciones JavaScript para la industria
empresarial bancaria y personal, al mismo tiempo que escrito y revisado la mayoría
del contenido de este sitio.
Add a comment...
Reply
Reply
muy.bueno!
Reply
Reply
Leave a Reply
Name, (required)
Website
Conocimientos generales
Publicaciones recientes
Renderer Tooltip
Estilo de un Botón
Ventana Login
Tabs Dinamicos