La clase Options nos facilitará mucho la vida a la hora de hacer sistemas personalizables y configurables por el programador. Nos ahorrará además muchas líneas de código cuando queramos crear objetos que se puedan personalizar por una serie de parámetros y nos permitirá definir unas opciones por defecto, que tengan validez cuando el programador no especifique todos los valores de configuración de los objetos que se instancien.
La importancia de conocer la clase Options y utilizarla cuando creemos componentes Mootools, se percibe sobre todo cuando la incorporamos al conjunto de recursos utilizados en nuestro día a día como desarrolladores Javascript. Observaremos al poco tiempo que resulta muy cómoda de usar y que nos da unas posibilidades enormes de reutilización de los componentes, personalización de sus funciones, así como la posibilidad de extender fácilmente las clases con nuevas funcionalidades, sin que ello implique reformar el código fuente de nuestras páginas en varios sitios para utilizar las nuevas versiones de las clases. En cualquier caso, en este artículo del Manual de Mootools de DesarrolloWeb.com esperamos que puedas apreciar todas las ventajas de uso de esta clase.
Podría venir bien un ejemplo para que las personas puedan entender cómo la clase Options nos permite organizar la inicialización de los objetos. Pensemos que hemos desarrollado un componente para crear un popup DHTML. Este popup mostraría un texto en una capa emergente y se podría configurar indicando su altura y la anchura. Por ejemplo el código para construir un popup como este podría ser:
var miPopup (enlace, texto, anchura, altura);
Todos esos datos podría necesitarlos el constructor. El enlace (del primer parámetro "enlace") sería el identificador del enlace o elemento que, cuando se hace clic sobre él, provoca que se abra la ventana emergente. El resto de datos texto, anchura y altura se deben indicar para configurar el popup.
Bueno, pues pensemos que dentro de unos días queremos configurar otras cosas como el color de fondo del popup, si tiene o no un botón para cerrar, si queremos que dentro del popup se muestre una página distinta por medio de un iframe, si se quiere poner un titular en la ventana del popup, etc. Ahora el constructor para crear la ventana podría tener esta forma:
var miPopup (enlace, texto, anchura, altura, fondo, cerrar, URLIframe, titular);
Esto nos podría obligar a cambiar todos los constructores que abren popups con la versión anterior de la clase, para incorporar todos los nuevos parámetros, o crear distintas versiones del popup, una sencilla y otra compleja. O bien hacer una única clase que tendría un buen pedazo de código sólo para hacer la comprobación de si existe o no ese parámetro en el constructor y dar un valor por defecto para cada uno de los datos que no se hayan indicado. Todo esto es un trabajo que puede llegar a ser pesado y además innecesario.
Sería mucho mejor hacer algo como esto:
var miPopup (enlace, opciones)
El constructor del popup sería siempre el mismo, con dos parámetros, el enlace que provoca la apertura de la capa emergente y unas cuantas opciones, que podrían incluso omitirse y simplemente tomar los valores por defecto. Lo mejor es que implementar esas opciones por medio de la clase Options es un paso casi inmediato que nos ahorrará además gran cantidad de código Javascript.
miEfecto = new Fx.Tween("micapa", {
property: 'color',
duration: 'slow',
fps: 20
});
Podemos ver que el constructor de Fx.Tween recibe como parámetros el elemento sobre el que se está creando el efecto y diversas otras opciones indicadas entre llaves. Esas opciones se indican con notación de objetos, indicando el nombre de opción y su valor. Realmente la clase Fx.Tween tiene varias opciones adicionales que se pueden configurar, pero nosotros sólo estamos indicando unas cuantas. Internamente lo que hace Fx.Tween es implementar la clase Options y los datos que recibe los procesa por medio de un método definido en la clase Options. Nosotros podemos hacer lo mismo en nuestras propias clases con muy poco esfuerzo.
Cuando programamos cualquier clase, donde pretendamos aprovechar las posibilidades de configuración y personalización de los objetos, tenemos que implementar la clase Options. Para indicar esto tenemos que utilizar la palabra Implements y el nombre de la clase que deseamos implementar, en este caso "Options" (con mayúscula inicial).
var MiClaseOpciones = new Class({
Implements: Options,
//código de nuestra clase...
});
Luego, dentro de la clase que estamos programando, tenemos que indicar las opciones por defecto de la clase por medio de la propiedad "options" (con la inicial en minúscula en este caso). Estas opciones por defecto serán indicadas en formato de objeto, con pares llave, valor, pudiendo definir como valores incluso funciones. Podemos indicar las opciones por defecto justo debajo de la línea del Implements: Options.
var MiClaseOpciones = new Class({
Implements: Options,
options: {
'opcion1': 'valor de cadena',
'otraOpcionNumerica': 45,
'otraOpcionFuncion': function(){
//código de la función
}
},
//resto del código de nuestra clase...
});
Como se puede ver, se indican tantas opciones como se desee, del tipo que necesitemos, y los valores que deben tomar por defecto.
En el constructor de esta clase de ejemplo que implementa Options recibiremos como parámetros tantos datos como sean necesarios y además una variable con las opciones de personalización que se quieran indicar para cada uno de los objetos a instanciar. Y además, muy importante, colocaremos una llamada al método setOptions() del propio objeto que se está creando, al cual le pasaremos las opciones de configuración de ese objeto recibidas como parámetro.
initialize: function(capa,opciones){
this.setOptions(opciones);
//resto del código del constructor
}
El método setOptions() recibe las opciones que se enviaron al constructor y se encarga de comprobar qué valores se han indicado y, si no existe alguno, marcar el valor por defecto indicado en la clase.
A este constructor podríamos llamarle con un código como este:
var miObjetoClaseMiClase = new MiClaseOpciones("capa", {
'opcion1': 'valor xxxxxx',
'otraOpcionFuncion': function(){
//código de la función
}
});
Como vemos, las opciones que enviamos para procesar con la clase Options, que estamos pasándole al constructor en el segundo parámetro, tienen varios valores en una notación de objeto. De las tres opciones de configuración de la clase miObjetoClaseMiClase, sólo se están indicando dos de ellas, luego la a omitida se le asignará el valor por defecto configurado en la propiedad options clase.
En cualquier lugar del código de la clase podremos acceder a las opciones de configuración del objeto, ya se hayan indicado al hacer el objeto o se hayan tomado por defecto. Para ello disponemos de la propiedad options, que utilizamos de esta manera:
this.options.otraOpcionNumerica
var CapaEfectos = new Class({
///implemento Options
Implements: Options,
//defino las options por defecto
options: {
fondoTransformar: '#000',
anchuraTransformar: 100,
textoTransformar: '#fff'
},
//constructor que recibe las options para cada objeto que se cree.
initialize: function(capa,opciones){
this.capa = $(capa);
this.setOptions(opciones);
var myFx = new Fx.Morph(this.capa, {duration: 'long'});
myFx.start({
'width': [this.capa.getStyle('width'), this.options.anchuraTransformar],
'background-color': [this.capa.getStyle('background-color'), this.options.fondoTransformar],
'color': [this.capa.getStyle('color'), this.options.textoTransformar]
});
}
});
Ahora, si lo deseamos, podemos añadir el código para usar esa clase y genera efectos de varios tipos, donde definimos unas u otras opciones.
window.addEvent("domready", function(){
$("sinopciones").addEvent("click", function(){
var efectosSinOpciones = new CapaEfectos("micapa");
});
$("conopciones").addEvent("click", function(){
var efectosSinOpciones = new CapaEfectos("micapa", {
fondoTransformar: '#0000ff',
anchuraTransformar: 500
});
});
$("otrasopciones").addEvent("click", function(){
var efectosSinOpciones = new CapaEfectos("micapa", {
fondoTransformar: '#0f0',
anchuraTransformar: 350,
textoTransformar: '#009'
});
});
});
Como se puede ver, se instancian varios objetos de la clase CapaEfectos, indicando en su constructor opciones diferentes.
Podemos ver el enlace al ejemplo en funcionamiento.