2009-06-23 11 views
31

Adoro l'architettura del plugin jQuery, tuttavia, trovo frustrante (probabilmente a causa di una mancanza di comprensione da parte mia) quando voglio mantenere un riferimento all'istanza del plugin per accedere alle proprietà o metodi più avanti nel mio codice.Funzioni pubbliche da un plug-in jQuery

Edit: Ci tengo a precisare che quello che sto davvero cercando di fare è mantenere un riferimento ai metodi e le proprietà utilizzati all'interno del plugin, in modo che io possa utilizzare in seguito

Consente di prendere il caso di un'icona di caricamento AJAX. In un ambiente di programmazione orientata agli oggetti più tradizionale, che potevo fare:

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

I metodi e le proprietà di mio oggetto sono memorizzati su una variabile per un uso successivo. Ora, se voglio avere la stessa funzionalità in un plugin jQuery, lo chiamerei dal mio codice principale un po 'come questo:

$("#myId").ajaxIcon() 

Per convenzione, il mio plug-in deve restituire l'oggetto jQuery originale passato al mio plug-in che consente per la chainability, ma se lo faccio, perdo la possibilità di accedere ai metodi e alle proprietà dell'istanza del plugin.

Ora, so che è possibile dichiarare una funzione pubblica nella mia plug-in, un po 'sulla falsariga di

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

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

Tuttavia, senza rompere la convenzione di restituire l'oggetto originale jQuery, non riesco a mantenere una riferimento alla specifica istanza del plugin a cui voglio riferirmi.

mi piacerebbe essere in grado di fare qualcosa del genere:

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

Qualche idea?

risposta

89

Se fate qualcosa di simile al seguente:

(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); 

Quindi è possibile accedere a qualsiasi dei tuoi metodi pubblici:

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

myPlugin.bar(); 

questo è preso da questo very helpful article (maggio 2009) da trulyevil.com che è di per sé un'estensione su this article (ottobre 2007) da learningjquery.com.

+1

Questo è un metodo eccellente, anche al di là di quello che spieghi qui ... come posso fare qualcosa come var myPlugin = $ ('id'). MyPlugin(). OtherFunction(). Hide() e myPlugin avrà ancora il funzioni corrette, poiché vengono aggiunte al nodo DOM che viene passato alla funzione jQuery. – Daniel

+0

Dopo alcuni giorni se si cerca di capirlo, grazie a Dio questo è qui .. C'è qualche sviluppo su questo dal 2009? – Ryan

+0

Grazie per i consigli utili :) –

-1

La maggior parte dei plugin jQuery che vedo provando a fare ciò userà un ambito anonimo e chiusure per fare riferimento a funzioni e variabili univoche per quell'istanza. Ad esempio, utilizzando il seguente schema:

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

Tra l'inizio e la fine del modulo, è possibile dichiarare le funzioni desiderate. Non inquinerai lo spazio dei nomi globale e potrai mantenere l'accesso alle variabili locali attraverso chiusure, che potrebbero risolvere molti dei tuoi problemi. Inoltre, non aver paura di utilizzare le funzioni $.data.

+0

hmm .... penso che le mie domande non siano abbastanza chiare. Ottengo come creare un plugin jQuery, con le chiusure e quant'altro, ma quello che voglio veramente sapere è come accedere alle istanze esistenti del plugin per accedere alle proprietà e ai metodi di innesco. – Daniel

0

Penso che si potrebbe realizzare quello che stai cercando con qualcosa di simile:

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

non ho ancora testato, però - non ho accesso a un ambiente in cui posso farlo atm

2

Ok, ho capito come fare questo:

codice del 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; 
} 

Poi usarlo da qualche altra parte nel codice:

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

voilà, risposto alla mia domanda proprio :)

+0

Hai trovato questo esempio da qualche altra parte, perché mi piacerebbe sapere un po 'di più sui bit di dati - sembra sciocco che il chiamante deve sapere di questo durante la creazione di un'istanza. – DEfusion

+0

In realtà su ulteriori ricerche non devi scherzare con tutto questo, vedi la mia risposta. – DEfusion

+1

Il metodo di DEfusion è molto meglio ... non userei questo metodo a meno che tu non voglia collegare le funzioni direttamente nel DOM per qualche motivo. – Daniel

Problemi correlati