Ejecutar una función de JavaScript con nombre dinámico

JavaScript
Hace tiempo estuve trabajando en una Aplicación Web, la cual estaba desarrollada en .Net (ASP NET y C#), ademas de usar Ajax y jQuery. Trabaje con el patrón MVC (Modelo-Vista-Controlador), el cual es un patrón de arquitectura de software que hace una separación de los datos, la interfaz y la lógica de control de una aplicación en tres componentes distintos.

Donde el Modelo corresponde a la lógica del negocio y a los datos con lo que la aplicación trabaja. La Vista es la representación gráfica de los datos, que en este caso serian los formularios y controles web donde se despliega la información. Y el Controlador que es el encargado de recibir y manejar las peticiones que hace la Vista al Modelado (aunque en ocasiones podría hacer peticiones a la misma Vista).

Como la aplicación estaba siendo desarrollada en .Net usando MVC, era muy común que usáramos Controles de Usuario (Web User Controls). Ciertos Controles de Usuario los usábamos varias veces en la misma pagina, lo cual era una ventaja (y su razón de ser) porque solo creábamos un solo Control para usarlo las veces que lo necesitásemos, hasta ahí todo bien pero . . .  recuerdan que al inicio les dije que usábamos jQuery y Ajax, pues he ahí el problema. Todos los Formularios y Controles de Usuario tenían su propio archivo JavaScript para realizar sus operaciones, y en el caso de los Controles su archivo JavaScript se cargaba una vez por cada ves que fuera usado, o sea que si un Control lo usábamos 3 veces en la misma pagina su JavaScript también se cargaría tres veces.

Entonces teníamos que resolver ese pequeño problema, lo primero que se viene a la mente es crear el JavaScript de manera dinámica por cada uso del control, esto lo podríamos lograr cargando el JavaScript con un Generic Web Handler (en post futuros hablaremos de ellos).

  • Usando el ClientID del Control de Usuario para anteponerlo al inicio de cada funcion del archivo JavaScript, para saber a que referencia del Control pertenece. La definición de las funciones seria algo como lo siguiente:
function MyControlID_MyFunction() { ... }

De esa manera todas las funciones serán diferentes dado que los ClientID de cada control son distintos, pero no cantemos victoria aun porque aun queda la parte “difícil”, ¿cómo mandaremos ejecutar esas funciones si no sabemos como se llaman?. Después de mucho buscar por Google y de probar varias maneras de hacerlo, termine por mezclar varias de ellas y logre hacer lo que necesitaba.

  • Como cada pagina tiene su propio archivo JavaScript y los Controles de Usuario están contenidos dentro de ella, lo que hice fue pasarle el ClientID de los controles al JavaScript de la pagina, y ya con eso podría formar el nombre de la función y mandarla llamar cuando fuese necesario. El codigo quedaria de la siguiente manera:
window[MyControlID + "_MyFunction"].apply(this, []);

Lo que hacemos básicamente es que mediante el objeto window accedemos a la función que deseemos ejecutar usando su nombre como id (la forma es parecida a obtener el valor de un registro en un diccionario en C#), porque como sabemos en JavaScript el objeto window es el que tiene el nivel jerárquico mas alto y todo esta contenido dentro de él, ya que representa la ventana del navegador. Enseguida del nombre de la función viene el uso del método “apply” el cual nos permitirá el envió de valores como parámetros, los cuales deben de ir entre los corchetes.

  • El llamado a la función enviandole valores seria de la siguiente manera:
window[MyControlID + "_MyFunction"].apply(this, ["Hello", "stranger"]);
  • Y para leer los valores que enviamos lo hacemos de la siguiente manera:
function MyControlID_MyFunction() { alert(arguments[0] + " " + arguments[1]); }

Como ven no es necesario declarar o indicar el nombre de los parámetros que se recibirán, dado que el objeto arguments es una variable local de cualquier función que contiene los valores que recibe como parámetros, los cuales con almacenados en un arreglo comenzando el indice en cero. Aunque de igual manera podrían escribirles el nombre para evitar confusiones.


El código aunque muy corto, me fue muy útil, espero y también pueda serlo para ustedes, funciona perfectamente en IE 7/8, Firefox y Chrome.

 

Have Fun!

2 comentarios para “Ejecutar una función de JavaScript con nombre dinámico”

  • Anibal says:

    El articulo esta muy bien, pero hay cosas que no me quedan claras…

    dices que hay que llamar a la funcion:
    function MyControlID_MyFunction() { … }

    ¿Como hago eso si por ejemplo tengo ésta funcion?

    function DetailsEntityViewImage() {
    var handlerPage = ”;
    var queryString = ‘?randomno=’ + getRandomNumber();
    var src = handlerPage + queryString;
    document.getElementById(”).setAttribute(“src”, src);
    }

    Es una funcion dentro de un control de usuario, este control de usuario se carga en una pagina aspx dinamicamente… es decir, que se pueden cargar una o mas veces en la misma pagina.

    Estoy intentando invocar dicha funcion desde el codigo servidor de cada control de usuario:

    lenguage DelphiPrism (Oxygene):

    ScriptManager.RegisterStartupScript(self, self.GetType, “DetailsEntity”, “DetailsEntityViewImage”, true);

    Pero no se ejecuta…
    ¿Me echais un cable, please?


  • Anibal says:

    El articulo esta muy bien, pero hay cosas que no me quedan claras…

    dices que hay que llamar a la funcion:
    function MyControlID_MyFunction() { … }

    ¿Como hago eso si por ejemplo tengo ésta funcion?

    function DetailsEntityViewImage() {
    var handlerPage = ”;
    var queryString = ‘?randomno=’ + getRandomNumber();
    var src = handlerPage + queryString;
    document.getElementById(”).setAttribute(“src”, src);
    }

    Es una funcion dentro de un control de usuario, este control de usuario se carga en una pagina aspx dinamicamente… es decir, que se pueden cargar una o mas veces en la misma pagina.

    Estoy intentando invocar dicha funcion desde el codigo servidor de cada control de usuario:

    lenguage DelphiPrism (Oxygene):

    ScriptManager.RegisterStartupScript(self, self.GetType, “DetailsEntity”, “DetailsEntityViewImage”, true);

    Pero no se ejecuta…
    ¿Me echais un cable, please?


Gracias por compartir tu opinión en esta nota

Para que tu avatar aparezca en los comentarios de este y otros blogs debes ser usuario registrado en Gravatar, puedes registrarte en el siguiente enlace: http://en.gravatar.com/site/signup
Stay Geek!

Deja un comentario

Sitios Amigos
Únete en Facebook
Síguenos en Twitter
Publicaciones Favoritas