2009-06-23 13 views
31

Me encanta la arquitectura del complemento jQuery, sin embargo, me parece frustrante (probablemente debido a una falta de comprensión de mi parte) cuando quiero retener una referencia a la instancia del complemento para acceder a las propiedades o métodos más adelante en mi código.Funciones públicas desde un plugin jQuery

Editar: Quiero aclarar que lo que yo estoy tratando de hacer es mantener una referencia a los métodos y propiedades que se utilizan dentro del plug-in, para que pueda usarlos más tarde

Tomemos el caso de un ícono de carga de AJAX. En un entorno de programación orientada a objetos más tradicional, lo que podía hacer:

var myIcon = new AJAXIcon(); 
myIcon.start(); 
//some stuff 
myIcon.stop(); 

Los métodos y propiedades de mi objeto se almacenan en una variable para su uso posterior. Ahora bien, si yo quiero tener la misma funcionalidad en un plugin de jQuery, yo diría que es de mi código principal algo como esto:

$("#myId").ajaxIcon() 

Por convención, mi plugin necesita para devolver el objeto jQuery originales pasado a mi plug-in que permite para la capacidad de recuperación, pero si lo hago, pierdo la capacidad de acceder a los métodos y las propiedades de la instancia del complemento.

Ahora, sé que se puede declarar una función pública en mi plugin, tanto en la línea de

$.fn.ajaxIcon = function(options) { 
    return this.each(function() { 
     //do some stuff 
    } 
} 

$.fn.ajaxIcon.stop = function() { 
    //stop stuff 
} 

Sin embargo, sin romper la convención de la devolución del objeto original jQuery, no puedo retener una referencia a la instancia específica del complemento al que me refiero.

Me gustaría ser capaz de hacer algo como esto:

var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon 
myIcon.start(); 
//some stuff 
myIcon.stop(); 

¿Alguna idea?

Respuesta

89

Si haces algo como lo siguiente:

(function($){ 

$.fn.myPlugin = function(options) { 
    // support multiple elements 
    if (this.length > 1){ 
     this.each(function() { $(this).myPlugin(options) }); 
     return this; 
    } 

    // private variables 
    var pOne = ''; 
    var pTwo = ''; 
    // ... 

    // private methods 
    var foo = function() { 
     // do something ... 
    } 
    // ... 

    // public methods   
    this.initialize = function() { 
     // do something ... 
     return this; 
    }; 

    this.bar = function() { 
     // do something ... 
    }; 
    return this.initialize(); 
} 
})(jQuery); 

A continuación, puede acceder a cualquiera de sus métodos públicos:

var myPlugin = $('#id').myPlugin(); 

myPlugin.bar(); 

esto está tomado de este very helpful article (mayo de 2009) de trulyevil.com, que a su vez es una extensión en this article (oct 2007) de learningjquery.com.

+1

Este es un método excelente, incluso más allá de lo que explicas aquí ... ya que puedo hacer algo como var myPlugin = $ ('id'). MyPlugin(). OtherFunction(). Hide(), y myPlugin todavía tendrá el funciones correctas, ya que se agregan al nodo DOM que se pasa a la función jQuery. – Daniel

+0

Después de unos días, si intentas resolver esto, gracias a Dios, esto está aquí. ¿Hay algo de desarrollo en esto desde 2009? – Ryan

+0

Gracias por los consejos útiles :) –

-1

La mayoría de los complementos de jQuery que veo tratando de lograr esto usarán un alcance anónimo y cierres para hacer referencia a funciones y variables exclusivas de esa instancia. Por ejemplo, usando el siguiente patrón:

;(function ($) { 
    // your code 
})(jQuery); 

Entre el comienzo y al final del módulo, puede declarar las funciones que desee. No contaminará el espacio de nombres global y podrá retener el acceso a variables locales a través de cierres, que podrían resolver muchos de sus problemas. Además, no tema utilizar las funciones $.data.

+0

hmm .... creo que mis preguntas no son lo suficientemente claras. Obtengo cómo hacer un plugin jQuery, con cierres y otras cosas, pero lo que realmente quiero saber es cómo acceder a las instancias existentes del complemento para acceder a las propiedades y activar los métodos. – Daniel

0

Creo que se podría lograr lo que usted está buscando con algo como esto:

var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon 
$.ajaxIcon.start(myIcon);//some stuff 
$.ajaxIcon.stop(myIcon); 

no lo he probado, aunque - no tengo acceso a un entorno en el que puedo hacer eso atm

2

Ok, me di cuenta de cómo hacer esto:

Código Plugin:

$.ajaxIcon.init = function(element, options) { 
    //your initialization code 

    this.start = function() { 
     //start code 
    } 

    this.stop = function() { 
     //stop code 
    } 
} 

$.fn.ajaxIcon = function(options) { 
    this.each(function() { 
     //This is where the magic happens 
     jQuery(this).data('ajaxIcon', new jQuery.ajaxIcon.init(this, opts)); 
    }); 

return this; 
} 

A continuación usarlo en otra parte de su código:

var myIcon = $("#myId").ajaxIcon.data('ajaxIcon') 
// myIcon: a reference to the 'init' object specific to this plugin instance 
myIcon.start(); 
myIcon.stop(); 

listo, respondió a mi propia pregunta :)

+0

¿Encontró esto como ejemplo en otro lugar, ya que me gustaría saber un poco más sobre los bits de datos? Parece tonto que la persona que llama necesita saber al crear una instancia. – DEfusion

+0

De hecho, en futuras investigaciones no tiene que perder el tiempo con todo esto, vea mi respuesta. – DEfusion

+1

El método de DEfusion es mucho mejor ... no usaría este método a menos que no desee adjuntar las funciones directamente al DOM por alguna razón. – Daniel