miércoles, 31 de enero de 2018

SAPUI5: Varios botones usando el mismo onPress

En el post anterior, vimos cómo crear un botón mediante Javascript, en lugar de hacerlo en la vista XML. Le añadimos un texto y una función que se ejecutaba cuando se pulsaba el botón, con el evento press.

Ahora vamos a ir un paso más allá, vamos a crear dos botones que hacen prácticamente lo mismo: Al pulsar cada uno de ellos, crea un nuevo botón con un texto. Si hemos pulsado el primer botón, el texto del botón será "Hola" y si hemos pulsado el segundo botón, el texto será "Mundo".

Además, si pulsamos alguno de los botones recién creados, mostrarán el texto "Hola" o "Mundo", respectivamente.



La funcionalidad para cada botón es, a todos los efectos, la misma, y sólo cambia el texto mostrado. Si vamos a añadir una funcionalidad nueva en un futuro, habrá que aplicarla igualmente a los dos botones.

El siguiente código haría lo que estamos buscando. A cada uno de los dos botones le añadimos como manejador del evento press una función específica (ver attachPress). Por tanto, si queremos añadir una nueva funcionalidad, habrá que replicarla dos veces.



Pero vamos a intentar hacerlo de otro modo: Vamos a crear una función única para ambos botones. Lo único que vamos a hacer es determinar qué botón hemos pulsado para asignar el texto correspondiente, pero el código será común.

Sí, podríamos hacer algo como esto:

oButton.attachPress( function() { this.mifuncioncomun(1); });

Donde le pasamos 1 o 2 para saber qué botón es. Pero queremos aprender un poco más, así que lo vamos a hacer de otra manera. Vamos a aprovechar que el evento press permite pasar un parámetro, oControlEvent, con el que podemos recuperar el botón que hemos pulsado. Yo voy a llamar a la función _crearBoton, que veremos más adelante.

Creando los dos botones que crean botones


Lo primero es recuperar la página y guardarla para poder reutilizarla más adelante, tanto en onInit como en _crearBoton:

this._oMiPagina = this.byId("mi_pagina");

Después, creamos dos botones como vimos en el post anterior, y le añadimos un id a cada uno para poder identificarlo.

var oButton = new Button( "el_id", { "text" : "el texto" } );

Pero ahora, al asignar el manejador, lo hacemos así:

oButton.attachPress( this._crearBoton, this );

Esto llamará a una función que definiremos así:

_crearBoton : function(evt) {}

Aunque en el attachPress no le estamos pasando parámetros, mirando la documentación, vemos que va a recibir un parámetro a partir del cual podemos recuperar el botón que ha invocado dicha llamada, mediante oControlEvent.getSource(). Yo no lo he llamado oControlEvent, sino evt, pero nos da igual, lo podemos llamar como queramos.

Por el momento, el código que tenemos en el onInit es:


¿Y por qué en el attachPress estamos pasando el parámetro this? 


El objeto this siempre hace referencia al objeto en el que nos encontramos. Cuando se ejecuta cualquier función desde el propio controlador (por ejemplo, el onInit), hace referencia al propio controlador.

Pero al llamar a la función _crearBoton desde un manejador de eventos, el this interno de _crearBoton será el objeto que ha invocado la función... es decir, el propio botón.

Sin embargo, nosotros queremos que el this de _crearBoton sea el propio controlador, porque así podemos reutilizar la página que hemos recuperado (this._oMiPagina). Lo que hacemos al pasar el this en el segundo parámetro del attachPress es "sobrescribir" el this de _crearBoton. Le estamos diciendo "oye, cuando ejecutes la función, si te digo que uses el this, me estoy refiriendo al controlador, no al botón".

Que lío, ¿verdad?

La función que crea botones


Ahora vamos a crear la función _crearBoton. Recordemos que le podemos pasar un parámetro, que yo he llamado evt. Con él, podremos recuperar el objeto que ha invocado la función. Y lo haríamos con esta llamada:

var oObjetoInvocador = evt.getSource();

Con ese objeto podemos recuperar cualquier propiedad del botón: el texto, el tipo, el ancho, cualquier agregado, lo que sea que esté asignado al botón. Eso incluye el ID del objeto, con la función getId(), que es común para todos los objetos.

No obstante, yo voy a usar otra opción que nos proporciona el evento, y es la posibilidad de recuperar parámetros. Uno de los parámetros del objeto es el id, y lo recuperaremos con:

evt.getParameter("id");

Como sólo necesito el id, con esto me vale, pero también os pongo el código para recuperarlo a través de getSource, comentado.

A partir del id, con un if-else podemos determinar el texto que vamos a mostrar, tanto en el botón como en el MessageToast. Y, tras ello, creamos el botón como ya hemos aprendido.

Lo único que nos falta es añadir el nuevo botón a la página. ¿Cómo lo hacemos? Como habíamos guardado la página en this._oMiPagina y en el attachPress le habíamos pasado como referencia de contexto el propio "this" del controlador, en _crearBoton tendremos en el this también la referencia al controlador y, por tanto, podemos usar this._oMiPagina y hacer:

this._oMiPagina.addContent(oButton);

Y ya está: Dos botones que crean más botones cuando los pulsamos.





No hay comentarios:

Publicar un comentario