2009-06-23 19 views
31

Uwielbiam architekturę wtyczek jQuery, jednak uważam ją za frustrującą (prawdopodobnie ze względu na brak zrozumienia z mojej strony), gdy chcę zachować odwołanie do instancji wtyczki, aby uzyskać dostęp do właściwości lub metody później w moim kodzie.Funkcje publiczne z wtyczki jQuery

Edit: Chciałbym wyjaśnić, że co ja naprawdę starają się zrobić, to zachować odniesienie do metod i właściwości wykorzystywanych wewnątrz wtyczki, tak że można je wykorzystać później

Weźmy przypadek ikona ładowania AJAX. W bardziej tradycyjnym środowisku OOP mógłbym:

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

Metody i właściwości mojego obiektu są przechowywane na zmiennej do późniejszego wykorzystania. Teraz, jeśli chcę mieć taką samą funkcjonalność w plugin jQuery, nazwałbym go z moim głównym kodu trochę tak:

$("#myId").ajaxIcon() 

umownie mój plugin musi powrócić do oryginalnego obiektu jQuery przekazany do mojego plugin pozwalający dla chainability, ale jeśli to zrobię, tracę możliwość dostępu do metod i właściwości instancji wtyczki.

Teraz wiem, że można zadeklarować funkcję publiczną w moim plugin, nieco na wzór

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

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

Jednak bez łamanie konwencji powrotu oryginalnego obiektu jQuery, nie mogę zachować odniesienie do konkretnej instancji wtyczki, której chcę się odwołać.

Chciałbym móc zrobić coś takiego:

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

jakieś przemyślenia?

Odpowiedz

89

Jeśli zrobić coś jak następuje:

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

Następnie można uzyskać dostęp do dowolnego Twoich publicznych metod:

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

myPlugin.bar(); 

To jest wzięte z tego very helpful article (maj 2009) z serwisu realevil.com, który sam jest rozszerzeniem na this article (październik 2007) od learningjquery.com.

+1

To jest doskonała metoda, nawet wykraczająca poza to, co tutaj wyjaśnisz ... ponieważ mogę zrobić coś takiego jak var myPlugin = $ ('id'). MyPlugin(). OtherFunction(). Hide(), a myPlugin nadal będzie poprawne funkcje, ponieważ są one dodawane do węzła DOM przekazywanego do funkcji jQuery. – Daniel

+0

Po kilku dniach, próbując to zrozumieć, dzięki Bogu, to jest tutaj. Czy jest jakiś postęp w tej dziedzinie od 2009 roku? – Ryan

+0

Dzięki za przydatne wskazówki :) –

-1

Większość wtyczek jQuery, które widzę, próbując to osiągnąć, będzie używać anonimowego zakresu i zamknięć do odwoływania się do funkcji i zmiennych unikalnych dla tej instancji. Na przykład przy użyciu następującego wzoru:

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

Pomiędzy początkiem i końcem modułu można zadeklarować dowolne żądane funkcje. Nie będziesz zanieczyszczać globalnej przestrzeni nazw i możesz zachować dostęp do zmiennych lokalnych poprzez zamknięcia, które mogą rozwiązać wiele twoich problemów. Ponadto, nie bój się korzystać z funkcji $.data.

+0

hmm .... Myślę, że moje pytania nie są wystarczająco jasne. Dostaję, jak zrobić wtyczkę jQuery, z zamknięciami i innymi, ale naprawdę chcę wiedzieć, jak uzyskać dostęp do istniejących instancji wtyczki, aby uzyskać dostęp do właściwości i metod wyzwalania. – Daniel

0

Myślę, że można osiągnąć to, czego szukasz w coś takiego:

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

nie testowałem go jednak - nie mam dostępu do środowiska, w którym mogę zrobić, że ATM

2

Ok, zorientowali się, jak to zrobić:

Kod 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; 
} 

Potem go używać gdzie indziej w kodzie:

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

voila, odpowiedział na moje własne pytanie :)

+0

Czy znalazłeś to jako przykład gdzie indziej, ponieważ chciałbym wiedzieć nieco więcej o bitach danych - wydaje się to głupie, że dzwoniący musi o tym wiedzieć podczas tworzenia instancji. – DEfusion

+0

Właściwie po dalszych badaniach nie musisz się z tym wszystkim kłopotać, zobacz moją odpowiedź. – DEfusion

+1

Metoda DEfusion jest znacznie lepsza ... nie użyłbym tej metody, chyba że nie chcesz dołączać funkcji bezpośrednio do DOM z jakiegoś powodu. – Daniel

Powiązane problemy