Публичные функции из плагина jQuery

мне нравится архитектура плагина jQuery, однако я нахожу ее разочаровывающей (возможно, из-за отсутствия понимания с моей стороны), когда я хочу сохранить ссылку на экземпляр плагина для доступа к свойствам или методам позже в моем коде.

Edit: я хочу уточнить, что я действительно пытаюсь сделать, это сохранить ссылку на методы и свойства, используемые в плагине, чтобы я мог использовать их позже

давайте рассмотрим случай загрузки AJAX икона. В более традиционной среде ООП я мог бы сделать:

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

методы и свойства объекта хранятся в переменной для дальнейшего использования. Теперь, если я хочу иметь ту же функциональность в плагине jQuery, я бы назвал его из моего основного кода примерно так:

$("#myId").ajaxIcon()

по соглашению, мой плагин должен вернуть исходный объект jQuery, переданный моему плагину с учетом цепочечности, но если я это сделаю, я потеряю возможность доступа к методам и свойствам экземпляр плагина.

теперь я знаю, что вы можете объявить публичную функцию в моем плагине, несколько по строкам

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

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

однако, не нарушая соглашение о возврате исходного объекта jQuery, я не могу сохранить ссылку на конкретный экземпляр плагина, на который я хочу ссылаться.

Я хотел бы иметь возможность сделать что-то вроде этого:

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

какие мысли?

4 ответов


Если вы делаете что-то вроде следующего:

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

тогда вы можете получить доступ к любому из ваших общедоступных методов:

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

myPlugin.bar();

это взято из этой очень полезная статья (май 2009) от trulyevil.com что само по себе является расширением на в этой статье (октябрь 2007) из learningjquery.com.


хорошо, я понял, как это сделать:

Код Плагина:

$.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;
}

затем использовать его где-то в коде:

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

вуаля, ответил на мой собственный вопрос:)


Я думаю, вы могли бы достичь того, что ищете, с чем-то вроде этого:

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

не протестировали его, Хотя - у меня нет доступа к среде, где я могу сделать это atm


большинство плагинов jQuery, которые я вижу, пытаясь выполнить это, будут использовать анонимную область и закрытие для ссылки на функции и переменные, уникальные для этого экземпляра. Например, используя следующий шаблон:

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

между началом и концом модуля, вы можете объявить любые функции, которые вы хотите. Вы не будете загрязнять глобальное пространство имен, и вы можете сохранить доступ к локальным переменным через закрытие, что может решить многие Ваши проблемы. Кроме того, не бойтесь используйте $.data функции.