Data Model

Los Data Model nos permiten representar las entidades de datos, junto con sus validaciones de formato y las relaciones con otros modelos, como si estos fuera objetos o clases. Por comparación podríamos pensar que un Data Model es como una clase (en POO) con la definición de los datos que la componen y funciones para poder validar y trabajar con esos datos.

A continuación podemos ver un esquema de todas las opciones que agrupa un Data Model, las cuales iremos viendo se las siguientes secciones:

Definir un modelo

Para crear un modelo usamos el constructor Ext.define('<Model-Name>', { ... }), en el que como primer parámetro indicamos el nombre del modelo a crear y como segundo parámetro recibe un objeto con la configuración del modelo. En la configuración de modelo tendremos que indicar dos cosas: que hereda de la clase Ext.data.Model y los campos que definen al modelo. Por ejemplo:

Ext.define('User', {    // Nombre del modelo: User
    extend: 'Ext.data.Model',
    config: {
        fields: [        // Descripción de los campos que lo componen
            { name: 'id', type: 'int' },
            { name: 'usuario', type: 'string' },
            { name: 'nombre',  type: 'string' },
            { name: 'genero',  type: 'string' },
            { name: 'activo',  type: 'boolean', defaultValue: true},
            { name: 'fechaRegistro', type: 'date', dateFormat: 'c' }
        ]
    }
});

En este ejemplo hemos creado el modelo User con cinco campos. Por defecto, en todos los modelos se asigna como identificador principal el campo id, el cual se utiliza para varias cosas (como saber si el modelo ha sido guardado). Si queremos variar el campo identificador podemos hacerlo con idProperty: 'id'.

Al heredar de la clase Ext.data.Model obtiene una serie de métodos y propiedades que nos van a permitir trabajar con los datos del modelo y almacenarlo de forma permanente.

En la sección fields se definen el resto de campos que componen el modelo. Para cada campo podemos utilizar:

  • name: nombre o identificador del campo.

  • type: los campos pueden ser de cinco tipos: string, int, float, boolean, date, auto.

  • defaultValue: atributo opcional que nos permite indicar el valor por defecto de un campo.

  • dateFormat: atributo opcional mediante el cual podemos indicar el formato de la fecha (ver http://docs.sencha.com/touch/2.4/2.4.1-apidocs/#!/api/Ext.Date).

Cuando se asigna el tipo auto o no se asigna ningún tipo el campo podrá obtener cualquier tipo de valor y no realizará ninguna validación de formato.

Crear una instancia de un modelo

Para crear una instancia de un modelo utilizamos también el constructor Ext.create('<Model-Name>', { ... }) especificando el nombre del modelo del cual queremos crear una instancia y un objeto con los valores a asignar a la instancia. Por ejemplo:

var ed = Ext.create('User', {
    usuario: 'ajgallego',
    nombre: 'Javier Gallego',
    genero: 'Masculino',
    activo: true
});

Validaciones

Los modelos de datos incluyen soporte para realizar validaciones, las cuales las deberemos de incluir dentro de la misma clase a continuación del campo fields. Por ejemplo:

Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            // ...
        ],
        validations: [
            { type: 'presence',  field: 'nombre' },
            { type: 'length',    field: 'nombre', min: 5 },
            { type: 'format',    field: 'usuario', matcher: /([a-z]+)[0-9]{2,3}/},
            { type: 'inclusion', field: 'genero', list: ['Masculino', 'Femenino'] },
            { type: 'exclusion', field: 'usuario', list: ['admin'] }
        ]
    }
});

Los tipos de validaciones que podemos utilizar son los siguientes:

  • presence: Indica que el campo es requerido.

  • length: Valida la longitud del campo. Podemos indicar como atributos un mínimo (min) y/o un máximo (max).

  • exclusion: Valida que el valor del campo no se encuentre entre la lista de valores especificados en list.

  • inclusion: Valida que el valor del campo se encuentre entre la lista de valores especificados en list.

  • format: Permite especificar una expresión regular (mediante el atributo matcher) para validar el campo.

Además, definiendo el valor de la propiedad message, podemos cambiar el mensaje de error que se produciría si una validación no es correcta:

{ field: 'titulo', type: 'presence',
  message: 'Por favor, introduzca un título' }

Cuando trabajemos con un formulario y queramos comprobar estas validaciones lo tendremos que hacer manualmente llamando a la función validate(). A continuación se incluye un ejemplo:

var newUser = Ext.create('User', {
    nombre: 'Javi',
    usuario: 'admin',
    genero: 'género no válido'
});

var errors = newUser.validate();

console.log('Válido?', errors.isValid()); // 'false' si hay errores
console.log('Errores:', errors.items); // array con los errores encontrados
console.log('Errores en género:', errors.getByField('genero'));

Además, como se puede ver en el ejemplo también disponemos de las funciones isValid() para comprobar si han habido errores, .items para obtener el array de errores encontrados y getByField('<nombre-del-campo>') para obtener los errores de un campo dado. En la sección de formularios se verá como integrar la validación de un modelo con un formulario.

Relaciones con otros modelos

Los modelos de datos también soportan la creación de relaciones con otros modelos de datos, del tipo "hasMany" y "belongsTo". Estos contenidos se quedan fuera de este capítulo de introducción por lo que para obtener más información podéis consultar la web:

http://docs.sencha.com/touch/2.4/core_concepts/data/models.html

Uso de modelos de datos en una aplicación

Al crear un modelo lo que estamos haciendo en realidad es crear una nueva definición de una clase (y no una instancia de una clase). Se puede observar la diferencia en el constructor, ya que usamos Ext.define('<nombre-modelo>', { ... }); en lugar de Ext.create.

En estos casos, en los que creemos nuevas definiciones, estaremos obligados a cargarlos por separado. Para ello Sencha Touch incorpora un potente sistema que nos permite modularizar nuestro código siguiente el patron MVC muy fácilmente. Solamente tendremos que seguir los siguientes pasos:

  • Crear una fichero con el mismo nombre que el modelo dentro de la carpeta app/model. Si por ejemplo nuestro modelo se llama User el fichero se tendrá que llamar User.js.

  • El contenido del fichero del modelo seguirá la sintaxis que hemos visto hasta ahora pero añadiendo el espacio de nombres <nombre-app>.model.<nombre-modelo> al nombre del modelo, por ejemplo si nuestra aplicación se llamase MyApp y el modelo a crear User, el modelo tendría que quedar como el siguiente:

Ext.define('MyApp.model.User', {    // Nombre del modelo con espacio de nombres
    extend: 'Ext.data.Model',
    config: {
        fields: [
            { name: 'id', type: 'int' },
            { name: 'name', type: 'string' }
        ]
    }
});
  • Por último tendremos que decirle a nuestra aplicación que cargue la definición del modelo para que podamos utilizarla. Para esto simplemente tenemos que hacer:

Ext.application({
    name: 'MyApp',
    models:['User'],
    launch: function() { ... }
});

A la hora de cargar el modelo podemos indicarlo usando solamente el nombre del modelo o usando el espacio de nombres completo (MyApp.model.User). Pero a la hora de utilizarlo (por ejemplo, para crear una instancia del modelo o asociarlo a un store) tendremos que usar la ruta del espacio de nombres completa.

Last updated