miércoles, 24 de enero de 2018

SAPUI5: Crear un elemento dinámicamente

Hasta ahora, en los ejemplos que hemos ido viendo para crear aplicaciones en SAPUI5, siempre hemos creado los objetos en la vista.

Pero resulta que podemos crear los objetos dinámicamente en el controlador mediante Javascript (o en una vista de tipo JS, claro). Esto nos va a permitir tener aplicaciones más complejas, en las que podamos decidir cuando hay que crear, modificar o eliminar un elemento y, además, no tenemos que definirlo obligatoriamente en la vista.

Vamos a verlo con un ejemplo facilito, y luego ya podremos buscar cosas más complicadas en posteriores posts. Partimos de una vista XML en la que sólo tenemos una página (sap.m.Page) y, en dicha página, añadiremos un botón que, al pulsar, nos mostrará un mensaje. Casi tan sencillo como destruir una Estrella de la Muerte.

¿Dónde vamos a codificar la creación del objeto? Pues como la vista es XML pero para crearlo necesitamos javascript, no nos queda otra que hacerlo en el controller.

Qué necesitamos saber


Para poder crear un objeto dinámicamente, tendremos que conocer el código (métodos, propiedades, eventos) que nos permita construir el objeto y modificar sus características. ¿Dónde podemos obtener esa información? Cómo no, en la SDK de SAPUI5. Ahí vamos a tener la información necesaria:

  • La definición del constructor para crear el objeto: new sap.m.Button.

  • Los métodos que podemos usar para modificar propiedades. Haremos una primera versión de la aplicación modificando las propiedades mediante estos métodos:
    • setText para asignar el texto;
    • attachPress para asignar una función que se ejecutará cuando salte el evento press. A este tipo de funciones se les llama manejadores, handlers.

  • Las propiedades y eventos que podemos asignar a la función cuando se crea el objeto. Haremos una segunda versión de la aplicación asignando las propiedades dentro del propio constructor.

Ante cualquier duda, a tirar de la documentación de SAPUI5, ahí se va la mitad de nuestro trabajo


Crear la aplicación


El primer paso es sencillo: crear una aplicación nueva de tipo SAPUI5, ya que no vamos a necesitar ningún servicio oData. Aquí no vamos a explicar nada porque lo hemos visto en posts anteriores.

El único paso adicional que vamos a hacer, una vez creada la aplicación, es darle un identificador a la página (sap.m.Page) que se crea por defecto para este tipo de aplicaciones. Este identificador lo asignamos en el atributo id y tiene que ser un nombre unívoco, no deben existir dos elementos con el mismo id en la aplicación.

<Page id="nombre_que_le_quiero_dar" ...>


¿Para qué nos va a valer esto? Para luego poder recuperar la página desde el controlador, asignándola a una variable y así le podremos añadir nuestro botón dentro del contenido (content).

Podríamos no asignarle ID y aún así recuperar la página por código, pero así podría complicarse la cosa, sobre todo en posteriores ampliaciones de la aplicación, y no tiene sentido teniendo en cuenta que la aplicación la hacemos de cero (si fuese una ampliación del estándar, ya sería otro cantar).

Crear el botón mediante métodos


Venga, que ya lo tenemos casi. Ahora accedemos al controlador y creamos la función onInit.

Dentro de ella, creamos el botón mediante la siguiente forma:

var oButton = new sap.m.Button();

Esto creará un objeto y lo asignará a la variable oButton, que luego podemos usar para modificar las propiedades del botón mediante las funciones: oButton.setText, oButton.attachPress...

OJO: Si miramos el código más adelante, veremos que sólo he puesto new Button() y no new sap.m.Button(). Eso es porque he definido, al inicio del controlador, la librería "sap/m/Button" e indico que la abrevio con Button. Lo podemos ver en el inicio del controlador. Así no tengo que escribir luego tanto texto, que aquí ahorramos más que escribiendo en el Whatsapp.

sap.ui.define([
    "libreria1",
    "sap/m/Button",
    "libreria3"
], function ( abreviatura1, Button, abreviatura2) { ... }


Ahora vamos a añadir el texto y el evento. Para eso, usamos dos métodos:

  • setText para añadir el texto que se verá en el botón.
  • attachPress para añadir una función que se ejecutará cuando se pulse el botón. La función va a mostrar un mensaje, que visualizaremos con el método sap.m.MessageToast.show

El evento press nos permite añadir un parámetro, attachPress( function(evento) {}),
pero como en el ejemplo no me aporta nada, no lo he añadido.

Ya hemos creado el botón, tiene un texto y ejecuta una función. Pero si ejecutamos la aplicación, no se verá nada. ¿Por qué? Porque nos falta ubicar el botón en la aplicación. Si lo creamos pero no lo insertamos en ningún sitio, se quedará perdido en el plano etéreo de los objetos perdidos.

Para asignarlo, debemos buscar un elemento que permita añadirle objetos, una especie de layout. En nuestro caso, la página a la que habíamos asignado un id tiene una agregación, content, donde podemos asignar el botón. Lo conseguiremos de la siguiente forma:


  • Recuperamos el objeto mediante var oPage = this.byId(identificador_de_la_pagina).
    Gracias a this.byId, podemos recuperar cualquier elemento identificado con un id de la vista actual.
    También podemos verlo en otros códigos como this.getView().byId("identificador"), ya que en las primeras versiones siempre teníamos que recuperar la vista (con getView) para luego poder buscar los elementos de la misma, pero eso cambio en algún momento que ahora no recuerdo... ¿la 1.28?

  • Añadimos el botón a la página mediante oPage.addContent.


Botón añadido a la página

Y si ahora ejecutamos la aplicación, ya tenemos nuestro botón y el evento asignado.


Como os podéis imaginar, jugando con los ids de los elementos y el byId, podríamos recuperar cualquier elemento de la vista, modificar sus propiedades, añadir manejadores de eventos.

Crear el objeto completo en el constructor


Cuando ya hemos comenzado a crear muchos componentes, en ocasiones nos da pereza eso de enlazar más y más métodos para cambiar las propiedades. Lo que podemos hacer para evitar esto, es asignar las propiedades directamente en el constructor.

El constructor del objeto Button permite, como muchos otros, dos tipos de parámetros: El identificador y un mapa de propiedades, en formato JSON. Eso quiere decir que, dentro del propio constructor, podemos asignar las propiedades en lugar de tener que usar los métodos setText y attachPress.

Lo que hacemos es ver las propiedades del elemento en la SDK y le pasamos aquellas que queramos modificar con formato JSON, de la siguiente forma:

var oButton = new Button( "id_opcional",
{
  "propiedad1" : valor,
  "propiedad2": valor2,
  "evento1" : funcion
}
);

Sólo tenemos que pasar las que queramos, y en el orden que queramos.

Sí, al principio parece un poco lío, pero luego te vas acostumbrando ;).

Después, ya sólo es asignar el botón a la página, como antes:


Agrupando a lo bestia


Todo el código anterior se puede agrupar, para no tener tantas líneas de código, aunque puede ser más complicado de entender. Como siempre, cada programador tiene su forma de desarrollar.

El siguiente código sería lo mismo que el que hemos hecho hasta ahora, sólo que sin definir explícitamente ni una sola variable.

Aquí hay que fijarse más detalladamente en lo que pone


2 comentarios:

  1. Como siempre fue un place leer tu post , explicas muy bien y de forma clara y gracias por aclarar eso de getView().byId() :D ya estoy recomendado este foro al unico programador sapui5 que conozco xD

    ResponderEliminar