Top Banner
Las grandes aplicaciones del lado del cliente han sido siempre difíciles de escribir, difícil de organizar y difícil de mantener. Tienden a crecer rápidamente sin control a medida que agrega más funcionalidad y desarrolladores a un proyecto. Ext JS 4 viene con una nueva arquitectura de aplicación que no sólo organiza su código, sino que tambien reduce la cantidad de codigo que se debe escribir. Nuestra arquitectura de la aplicación sigue un patrón como el MVC- con modelos y controladores que están siendo introducidos por primera vez. Hay muchas arquitecturas MVC, la mayoría de los cuales son ligeramente diferentes entre sí. A continuación mostramos cómo se define la nuestra: Un modelo es una colección de campos y sus datos (por ejemplo, un modelo de usuario con nombre de usuario y las contraseñas). Los Modelos saben cómo se persisten a través del paquete de datos, y puede estar vinculado a otros modelos a través de asociaciones. Los Modelos trabajan de forma muy similar a la clase Record de Ext JS 3, y se utilizan normalmente con Stores para presentar los datos en las grillas y otros componentes. Vista es cualquier tipo de componente – grids, trees and panels son todos ellos vistas . Controladores son lugares especiales para poner todo el código que hace que su aplicación funcione – ya sea el renderizado de vistas, creación de instancias de Modelos, o cualquier otra lógica de aplicación. En esta guía vamos a crear una aplicación muy sencilla que gestiona los datos del usuario. Al final usted sabrá cómo juntar aplicaciones sencillas, usando la nueva arquitectura de aplicación de Ext. JS 4. La arquitectura de la aplicación trata tanto de proporcionar la estructura y consistencia, tanto para las clases del framework como las de su aplicación. Seguir las convenciones tiene una serie de ventajas importantes:
26

Manual Extjs

Jan 20, 2016

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Manual Extjs

Las grandes aplicaciones del lado del cliente han sido siempre difíciles de escribir, difícil de organizar y difícil de mantener. Tienden a crecer rápidamente sin control a medida que agrega más funcionalidad y desarrolladores a un proyecto. Ext JS 4 viene con una nueva arquitectura de aplicación que no sólo organiza su código, sino que tambien reduce la cantidad de codigo que se debe escribir.

Nuestra arquitectura de la aplicación sigue un patrón como el MVC- con modelos y controladores que están siendo introducidos por primera vez. Hay muchas arquitecturas MVC, la mayoría de los cuales son ligeramente diferentes entre sí. A continuación mostramos cómo se define la nuestra:

Un modelo es una colección de campos y sus datos (por ejemplo, un modelo de usuario con nombre de usuario y las contraseñas). Los Modelos saben cómo se persisten a través del paquete de datos, y puede estar vinculado a otros modelos a través de asociaciones. Los Modelos trabajan de forma muy similar a la clase Record de Ext JS 3, y se utilizan normalmente con Stores para presentar los datos en las grillas y otros componentes.

Vista es cualquier tipo de componente – grids, trees and panels son todos ellos vistas.

Controladores son lugares especiales para poner todo el código que hace que su aplicación funcione – ya sea el renderizado de vistas, creación de instancias de Modelos, o cualquier otra lógica de aplicación.

En esta guía vamos a crear una aplicación muy sencilla que gestiona los datos del usuario. Al final usted sabrá cómo juntar aplicaciones sencillas, usando la nueva arquitectura de aplicación de Ext. JS 4.

La arquitectura de la aplicación trata tanto de proporcionar la estructura y consistencia, tanto para las clases del framework como las de su aplicación. Seguir las convenciones tiene una serie de ventajas importantes:

Cada aplicación funciona de la misma manera por lo que sólo tiene que aprenderlo una vez.

Es fácil compartir código entre aplicaciones, ya que todas trabajan de la misma manera.

Usted puede utilizar nuestras herramientas de construcción para crear versiones de sus aplicaciones optimizadas para su uso en producción.

Estructura de archivos

Las aplicaciones Ext JS 4 siguen una estructura de directorio unificado que es el mismo para cada aplicación. Por favor, revise la Guía de introducción para una explicación detallada sobre la estructura básica de los archivos en una aplicación. En el diseño MVC, todas las clases se colocan en la carpeta app , que contiene a su vez sub-carpetas para generar el espacio de nombres de los modelos, vistas, controladores y almacenes(stores). Así es como la estructura de carpetas para nuestra simple aplicación de ejemplo se verá cuando haya terminado:

Page 2: Manual Extjs

En este ejemplo, se encapsula toda la aplicación dentro de una carpeta llamada ‘account_manager . Los archivos más importantes de la Ext JS 4 SDK están incluidas en la carpeta ext-4.0. Por lo tanto el contenido de nuestro index.htmles la siguiente:

<html><head> <title>Account Manager</title>

<link rel="stylesheet" type="text/css" href="ext-4.0/resources/css/ext-all.css">

<script type="text/javascript" src="ext-4.0/ext-debug.js"></script>

<script type="text/javascript" src="app.js"></script></head><body></body></html>

Page 3: Manual Extjs

Crear la aplicación en app.js

Cada aplicación Ext. JS 4 se inicia con una instancia de la clase Application . La instancia de Application contiene la configuración global de su aplicación (por ejemplo, el nombre de la aplicación), así como mantiene referencias a todos los modelos, vistas y controladores utilizados por la aplicación. Una aplicación también contiene una función de lanzamiento, que se ejecuta automáticamente cuando todo está cargado.

Vamos a crear una aplicación de Account Manager sencilla que nos ayudará a gestionar las cuentas de usuario. En primer lugar tenemos que elegir un espacio de nombres global para esta aplicación. Todos las aplicaciones Ext JS 4 sólo se debe utilizar una variable global, con todas las clases de la aplicación anidadas dentro de ella. Por lo general, queremos un nombre de variable global corta, en este caso vamos a utilizar “AM”:

Ext.application({ name: 'AM',

appFolder: 'app',

launch: function() { Ext.create('Ext.container.Viewport', { layout: 'fit', items: [ { xtype: 'panel', title: 'Users', html : 'List of users will go here' } ] }); }});Hay algunas cosas que pasan aquí. En primer lugar, invoca Ext.applicationpara crear una nueva instancia de clase de aplicación, a la que pasamos el nombre de ” AM “. Esto configura automáticamente una variable global AM por nosotros, y registra el espacio de nombres a Ext.Loader , con la ruta correspondiente de ‘app ‘ configurado a través de la opción de configuración appFolder . También proporciona una función de lanzamiento simple que sólo crea una Viewport que contiene un único panel que se llenara la pantalla.

Page 4: Manual Extjs

Definir un Controlador

Los controladores son como el pegamento que une todas las partes de la aplicación entre si. Todo lo que realmente hacen es escuchar los eventos (por lo general de vistas) y realizar algunas acciones cuando lleguen. Continuando con nuestra aplicación de Account Manager, vamos a crear un controlador. Cree un archivo llamado app/controller/Users.js y agregue el siguiente código:

Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller',

init: function() { console.log('Initialized Users! This happens before the Application launch function is called'); }});Ahora agregamos nuestro recientemente creado controlador Users a la configuración de la aplicación en app.js:

Ext.application({ ...

controllers: [ 'Users' ],

...

Page 5: Manual Extjs

});Cuando cargamos nuestra aplicación visitando index.html dentro de un navegador, el controlador Users se carga automáticamente (ya que se especifica en la definición de aplicación más arriba), y su la init se llama justo antes de la función launch de la aplicación.

La funcion init es un buen lugar para establecer cómo el controlador interactúa con la vista, y normalmente se utiliza en conjunción con otra función de Controller – control . La función control hace que sea fácil de escuchar a los eventos de las clases de sus vistas y realizar acciones con una función de controlador. Vamos a actualizar nuestro controlador Users para decirnos cuando el panel se renderiza:

Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller',

init: function() { this.control({ 'viewport &gt; panel': { render: this.onPanelRendered } }); },

onPanelRendered: function() { console.log('The panel was rendered'); }});Hemos actualizado la función init para usar this.control para establecer los oyentes en las vistas de nuestra aplicación. La función control utiliza el nuevo motor de ComponentQuery para obtener rápida y fácilmente las referencias a los componentes de la página. Si usted no está familiarizado con ComponentQuery, asegúrese de revisar la documentación de ComponentQuery para una explicación completa. En resumen, nos permite pasar de selector similar al CSS que buscara todos los componentes correspondientes en la página.

En nuestra función de inicio por encima de nosotros especificamos 'viewport > panel' , que se traduce en “me encuentra cada panel que es un hijo directo de una ventana”. A continuación, suministramos un objeto que asigna nombres de eventos (solo render en este caso) a las funciones de controlador. El efecto general es que cada vez que cualquiera de los componentes que coincide con nuestro selector dispara un evento render, nuestra función onPanelRendered es llamada.

Cuando ejecutamos nuestra aplicación ahora podemos ver lo siguiente:

Page 6: Manual Extjs

No es exactamente la aplicación más emocionante de la historia, pero demuestra lo fácil que es empezar con el código de organización. Permitamonos continuar un poco mas con la aplicación agregandole una grilla.

Definir una Vista

Hasta ahora nuestra aplicación sólo ha sido unas pocas líneas y sólo esta contenida en dos archivos – app.js y app/controller/Users.js. Ahora que queremos agregar una grilla que muestre todos los usuarios de nuestro sistema, es el momento de organizar nuestra lógica un poco mejor y empezar a usar vistas.

Una vista no es más que un componente, por lo general se define como una subclase de un componente de Ext JS. Vamos a crear nuestra grilla de usuarios ahora creando un nuevo archivo llamado app/view/user/List.js y poniendo lo siguiente en él:

Ext.define('AM.view.user.List' ,{ extend: 'Ext.grid.Panel', alias : 'widget.userlist',

Page 7: Manual Extjs

title : 'All Users',

initComponent: function() { this.store = { fields: ['name', 'email'], data : [ {name: 'Ed', email: '[email protected]'}, {name: 'Tommy', email: '[email protected]'} ] };

this.columns = [ {header: 'Name', dataIndex: 'name', flex: 1}, {header: 'Email', dataIndex: 'email', flex: 1} ];

this.callParent(arguments); }});Nuestra clase de Vista no es más que una clase normal. En este caso nos toca ampliar el componente de la grilla y configurar un alias para poder usarlo como un xtype (más sobre esto en un momento). También pasamos en el la configuración del almacén y las columnas que la grilla debe hacer.

A continuación tenemos que añadir esta vista a nuestro de nuestro controlador de usuarios. Debido a que establecimos un alias con el formato especial ‘widget.’ , ahora podemos usar “userlist” como un xtype, al igual que se había usado ‘panel’ previamente.

Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller',

views: [ 'user.List' ],

init: ...

onPanelRendered: ...});Y luego se renderizan dentro de la ventana principal, modificando el método de lanzamiento en app.js:

Page 8: Manual Extjs

Ext.application({ ...

launch: function() { Ext.create('Ext.container.Viewport', { layout: 'fit', items: { xtype: 'userlist' } }); }});Lo único a destacar aquí es que hemos especificado “user.List ‘dentro de la matriz vistas. Esto le dice a la aplicación que debe cargar el archivo de forma automática de manera que podamos usarlo cuando ejecutemos. La aplicación utiliza el nuevo sistema de carga dinámica de Ext JS 4 para obtener automáticamente el archivo desde el servidor. Esto es lo que veremos cuando recargemos la página ahora:

Page 9: Manual Extjs

Controlar la grilla

Observe que nuestra función onPanelRendered todavía está siendo llamada. Esto se debe a nuestra clase de la grilla sigue coincidiendo con el selector de “viewport> panel ‘. La razón de esto es que nuestra clase extiende Grid, que a su vez extiende Panel.

Por el momento, los oyentes que agregamos al de selección en realidad se llaman para cada Panel o o Subclase de Panel que sea un hijo directo de el viewport, así que vamos a ajustar un poco mas con nuestra nueva xtype. Mientras estamos con esto, vamos a escuchar en su lugar los hacer doble clic en las filas de la grilla de modo que más tarde se pueda editar el usuario:

Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller',

views: [ 'user.List' ],

init: function() { this.control({ 'userlist': { itemdblclick: this.editUser } }); },

editUser: function(grid, record) { console.log('Double clicked on ' + record.get('name')); }});Observe que hemos cambiado el de selección ComponentQuery (simplemente ‘userlist’), el nombre del evento (a ‘itemdblclick’) y el nombre de función de controlador (a ‘editUser’). Por ahora sólo estamos registrando el nombre del usuario que se hace doble clic:

Page 10: Manual Extjs

Registrarlo en la consola está muy bien, pero realmente queremos editar nuestros usuarios. Vamos a hacerlo ahora, comenzando con una nueva vista en el archivoapp/view/user/Edit.js:

Ext.define('AM.view.user.Edit', { extend: 'Ext.window.Window', alias : 'widget.useredit',

title : 'Edit User', layout: 'fit', autoShow: true,

initComponent: function() { this.items = [ { xtype: 'form', items: [ {

Page 11: Manual Extjs

xtype: 'textfield', name : 'name', fieldLabel: 'Name' }, { xtype: 'textfield', name : 'email', fieldLabel: 'Email' } ] } ];

this.buttons = [ { text: 'Save', action: 'save' }, { text: 'Cancel', scope: this, handler: this.close } ];

this.callParent(arguments); }});Una vez más estamos a definiendo una subclase de un componente existente - esta vez Ext.window.Window . Una vez más hemos utilizado initComponent para especificar los complejos elementos items y buttons Hemos utilizado una distribución "fit" y el formulario como un elemento único, que contiene los campos para editar el nombre y la dirección de correo electrónico. Finalmente hemos creado dos botones, uno que sólo cierra la ventana, y el otro que se utilizará para guardar los cambios.

Todo lo que tenemos que hacer ahora es agregar la vista en el controlador, renderizarla y cargar el usuario en ella:

Ext.define(‘AM.controller.Users’, {

<code id="ext-gen1263"> extend: 'Ext.app.Controller',

Page 12: Manual Extjs

views: [ 'user.List', 'user.Edit' ],

init: ...

editUser: function(grid, record) { var view = Ext.widget('useredit');

view.down('form').loadRecord(record); }});</code>Primero creamos la vista mediante el método práctico Ext.widget, lo que equivale a Ext.create ('widget.useredit'). Luego usamos ComponentQuery , una vez más para obtener rápidamente una referencia al formulario la ventana Editar . Todos los componentes de ExtJS 4 tiene una función down, que acepta un de selección ComponentQuery para encontrar rápidamente cualquier componente hijo.

Hacer doble clic en una fila en la grilla ahora muestra algo como esto:

Page 13: Manual Extjs

Definir un Modelo y un Almacén(Store)

Ahora que tenemos nuestro formulario de edición es casi la hora para empezar a editar los usuarios y guardar esos cambios. Antes de hacerlo, sin embargo, tenemos que refactorizar nuestro código un poco.

Por el momento en que el componente AM.view.user.List crea un Store en linea. Esto funciona bien, pero nos gustaría poder hacer referencia a esa tienda en otras partes de la aplicación para poder actualizar los datos en ella. Vamos a empezar por sacar el store fuera en su propio archivo - app/store/Users.js:

Ext.define('AM.store.Users', { extend: 'Ext.data.Store', fields: ['name', 'email'], data: [ {name: 'Ed', email: '[email protected]'}, {name: 'Tommy', email: '[email protected]'} ]});Ahora sólo tendremos que hacer dos pequeños cambios - en primer lugar le pediremos a nuestro controlador de Users incluir este store cuando se carga:

Ext.define('AM.controller.Users', { extend: 'Ext.app.Controller', stores: [ 'Users' ], ...});entonces actualizaremos app/view/user/List.js para simplificar las referencias al Store usando un id:

Ext.define('AM.view.user.List' ,{ extend: 'Ext.grid.Panel', alias : 'widget.userlist',

//we no longer define the Users store in the `initComponent` method store: 'Users',

Page 14: Manual Extjs

...});Mediante la inclusión de los Stores que hemos definido en nuestro controlador Users, estos son cargados automáticamente y se les da un store id, lo que les hace muy fácil de referenciar en nuestra vista (con sólo configurar store: 'Users' en este caso).

Por el momento acabamos de definir nuestros campos ('name' and'email') en línea en el Store. Esto funciona bastante bien, pero en Ext JS 4 tenemos una clase Ext.data.Model poderosa que nos gustaría aprovechar en lo que se refiere a la edición de nuestros usuarios. Vamos a terminar esta sección con la refactorización de el Store para utilizar un modelo que vamos a poner enapp/model/User.js:

Ext.define('AM.model.User', { extend: 'Ext.data.Model', fields: ['name', 'email']});Eso es todo lo que tenemos que hacer para definir nuestro modelo, ahora sólo tendremos que actualizar nuestro Store para hacer referencia al nombre del modelo en lugar de indicar los campos en linea, y también pedirle al controlador de Users obtener una referencia al modelo :

//El controlador Users nos asegurara que el modelo User es incluido en la página y esta disponible para nuestra aplicaciónExt.define('AM.controller.Users', { extend: 'Ext.app.Controller', stores: ['Users'], models: ['User'], ...});

// ahora referenciamos a el modelo en vez de definir los campos en lineaExt.define('AM.store.Users', { extend: 'Ext.data.Store', model: 'AM.model.User',

data: [ {name: 'Ed', email: '[email protected]'}, {name: 'Tommy', email: '[email protected]'} ]});Nuestra refactorización hará más fácil la próxima sección, pero no debería haber afectado el comportamiento actual de la aplicación. Si recargamos la página ahora y hacemos doble clic en una fila, vemos que la ventana de edición de usuario sigue apareciendo como se esperaba. Ahora es el momento de terminar la funcionalidad de edición:

Page 15: Manual Extjs

Guardar los datos con el Modelo

Ahora que tenemos a nuestra grilla cargada con los datos de los usuarios y se abre una ventana de edición cuando se hace doble clic en cada fila, nos gustaría guardar los cambios que realice el usuario. La ventana de edición de usuario que se definido anteriormente contiene un formulario (con los campos de nombre y correo electrónico), y un botón de guardar. En primer lugar vamos a actualizar la función init nuestro controlador para escuchar los clics al botón Guardar:

Ext.define('AM.controller.Users', { init: function() { this.control({ 'viewport &gt; userlist': { itemdblclick: this.editUser }, 'useredit button[action=save]': { click: this.updateUser } }); },

updateUser: function(button) {

Page 16: Manual Extjs

console.log('clicked the Save button'); }});Esta vez hemos añadido un segundo selector ComponentQuery a nuestro llamada a this.control - 'useredit button[action=save]'. Esto funciona de la misma manera que el primer selector - que utiliza el xtype 'useredit' que hemos definido anteriormente para enfocarse en la ventana de edición de usuario, y luego busca los botones con la acción del 'save'dentro de esa ventana. Cuando definimos nuestra ventana de edición de usuarios pasamos {action: 'save'} el botón de guardar, lo cual nos da una manera fácil de apuntar a ese botón.

Podemos verificar que la función updateUser sea llamada cuando se haga clic en el botón Guardar:

Ahora que hemos visto a nuestro manejador esté conectado correctamente a evento click del botón Guardar, vamos a llenar en la lógica real de la función UpdateUser. En esta función es necesario para obtener los datos del formulario, actualizar nuestros usuarios con ella y luego guardar ese regreso al Store usuarios que hemos creado anteriormente. Vamos a ver cómo podemos hacer lo siguiente:

updateUser: function(button) {

Page 17: Manual Extjs

var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues();

record.set(values); win.close();}Vamos a descomponer lo que está pasando aquí. Nuestro evento click nos dio una referencia al botón al que el usuario hizo clic, pero lo que realmente queremos es el acceso al formulario que contiene los datos y la propia ventana. Para obtener las cosas con rapidez sólo tendremos que utilizar ComponentQuery nuevamente, en primer lugar con button.up('window') para conseguir una referencia a la ventana de edición de usuario, entonces usamos win.down('form')para obtener el formulario.

Después de eso, simplemente debemos recuperar el registro que actualmente se encuentra cargado en del formulario y actualizarlo con lo que el usuario ha escrito en el formulario. Por ultimo, cerramos la ventana para llamar la atención de nuevo a la grilla. Esto es lo que vemos cuando ejecutamos nuestra aplicación, cambie el campo de nombre a 'Ed Spencer' y haga clic en Guardar:

Guardar en el servidor

Page 18: Manual Extjs

Es muy fácil. Vamos a terminar esto ahora haciendolo interactuar con nuestro servidor. Por el momento estamos harcodeando dos registros de ejemplo en el Store usuario, por lo que vamos a empezar leyendolos via AJAX en su lugar:

Ext.define('AM.store.Users', { extend: 'Ext.data.Store', model: 'AM.model.User', autoLoad: true,

proxy: { type: 'ajax', url: 'data/users.json', reader: { type: 'json', root: 'users', successProperty: 'success' } }});Aquí hemos eliminado la propiedad 'data' y lo reemplazamos con un proxy. Los proxys son la forma de cargar y guardar datos de un almacén(Store) o un Modelo en Ext JS 4. Hay Proxys de AJAX, JSON-P y HTML5 localStorage, entre otros. Aquí hemos utilizado un simple Proxy de AJAX, lo que le hemos dicho a cargar los datos desde la url 'data/users.json'.

También adjunta un lector para el proxy. El lector es responsable de la decodificación de la respuesta del servidor en un formato que el Store pueda entender. Esta vez hemos utilizado un lector de JSON, y especificado las configuraciones de root y successProperty(ver la documentación Json Reader para más información sobre las configuraciones). Por último vamos a crear nuestro ficherodata/users.json y pegar los datos anteriores en el:

{

success: true,

users: [

{id: 1, name: 'Ed', email: '[email protected]'},

{id: 2, name: 'Tommy', email: '[email protected]'}

]

}

Page 19: Manual Extjs

El único cambio que hicimos al Store es establecer autoLoad atrue, lo que significa que el Store le pedirá a su proxy cargar esos datos de inmediato. Si se actualiza la página ahora vamos a ver el mismo resultado que antes, excepto que ahora ya no estamos harcodeando los datos en nuestra aplicación.

Lo último que deseamos hacer aquí es enviar nuestros cambios de vuelta al servidor. Para este ejemplo, sólo estamos utilizando archivos estáticos JSON en el servidor por lo que no verá ningún cambio de base de datos, pero al menos podemos comprobar que todo está conectado correctamente en conjunto. En primer lugar vamos a hacer un pequeño cambio en nuestro nuevo proxy para decirle que envíe actualizaciones a una dirección URL diferente:

proxy: { type: 'ajax', api: { read: 'data/users.json', update: 'data/updateUsers.json' }, reader: { type: 'json', root: 'users', successProperty: 'success' }}Todavía estamos leyendo los datos del users.json, pero las actualizaciones serán enviadas a updateUsers.json. Esto es sólo para poder devolver una respuesta ficticia para saber que las cosas están funcionando. El archivo updateUsers.json contiene sólo{"success": true}. El único cambio que tenemos que hacer es indicar a nuestro Store sincronizarse después de la edición, lo cual hacemos mediante la adición de una línea más dentro de la función updateUser, que ahora se ve así:

updateUser: function(button) { var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues();

record.set(values); win.close(); this.getUsersStore().sync();}Ahora podemos desplazarnos a través de nuestro ejemplo completo y asegurarnos de que todo funciona. Vamos a editar una fila, pulsar el botón Guardar y ver que la solicitud se envía correctamente aupdateUser.json

Page 20: Manual Extjs

Despliege

La reciente introducción Sencha SDK Tools (descargar aquí) hace que la implementación de cualquier aplicación Ext JS 4 sea más fácil que nunca. Las herramientas que le permite generar un manifiesto de todas las dependencias en la forma de un archivo JSB3 (formato de archivo JSBuilder), o crear un compilado minimo de lo que su aplicación necesita en cuestión de minutos.

Por favor, consulte la guía de introducción para obtener instrucciones detalladas.

Siguientes Pasos

Hemos creado una aplicación muy sencilla que gestiona los datos del usuario y envía los cambios al servidor. Empezamos simple y poco a poco rediseñado nuestro código para hacerlo más limpio y más organizado. En este punto, es fácil agregar más funcionalidad a nuestra aplicación sin necesidad de crear código espagueti. El código fuente completo para esta aplicación se puede encontrar en la descarga de Ext JS SDK 4, dentro de la carpeta examples/app/simple.

En la siguiente guía, veremos el uso de controladores avanzados y los patrones que pueden hacer que su código de aplicación más pequeños y más fáciles de mantener.

Nota adicional: Si van a realizar el script php para actualizar los datos en la base, necesitaran saber antes como recibir los parametros enviados via JSON en PHP

Page 21: Manual Extjs

ExtJS 4.0 Documentation from Sencha , versión en español por Mario Pérez.