Публичные функции из плагина jQuery
Мне нравится архитектура плагина jQuery, однако я нахожу это неприятным (возможно, из-за недостатка понимания с моей стороны), когда я хочу сохранить ссылку на экземпляр плагина для доступа к свойствам или методам позже в моем коде.
Изменить: я хочу уточнить, что то, что я действительно пытаюсь сделать, это сохранить ссылку на методы и свойства, используемые в плагине, чтобы я мог использовать их позже
Давайте рассмотрим значок загрузки 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();
Любые мысли?
Ответы
Ответ 1
Если вы делаете что-то вроде следующего:
(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 г.) от Indeed.com, которая сама по себе является расширением на этой статьи (октябрь 2007) от learnjquery.com.
Ответ 2
Хорошо, я понял, как это сделать:
Код плагина:
$.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();
voila, ответил на мой собственный вопрос:)
Ответ 3
Я думаю, вы могли бы выполнить то, что ищете, например:
var myIcon = $("myId").ajaxIcon(); //myIcon = a reference to the ajaxIcon
$.ajaxIcon.start(myIcon);//some stuff
$.ajaxIcon.stop(myIcon);
Не проверял его, хотя у меня нет доступа к среде, где я могу сделать это atm
Ответ 4
Пример плагина со всеми функциями:
<script type="text/javascript">
(function( $ ) {
$.fn.PluginX = function( options ) {
// Default variables
// var defaults = {textColor: "#000", backgroundColor: "#fff"}
// var opts = $.extend( {}, defaults, options );
// Or
var settings = $.extend( {}, $.fn.PluginX.defaults, options );
// Private function
var privFunc = function(txt) {
return "Private function " + txt;
};
// Public function
this.pubFunc = function(txt) {
console.log("\r\nPublic function " + txt);
return this;
};
// Public function2
this.pubFunc2 = function(txt) {
console.log("\r\nPublic function " + txt);
// Private from public
privFunc("\r\nPrivate function from public -- " + txt);
return this;
};
// Our plugin implementation code goes here.
return this.each(function() {
// alert(opts.validate);
$(this).on('click',function(){
var elem = $( this );
var markup = elem.text();
console.log("\r\nElement text " + markup);
// Function private
console.log(privFunc(markup));
// External func
console.log($.fn.PluginX.format(markup));
// External function
console.log(external(markup));
});
return this;
});
};
// Variable
$.fn.PluginX.defaults = {
validate: "username"
};
// External Function
$.fn.PluginX.format = function(txt) {
return "<strong>" + txt + "</strong>";
};
// External Function
function external(txt){
return "External " + txt;
}
})(jQuery);
$(document).ready(function() {
var pl = $('.txt').PluginX({validate: "words"}).pubFunc("Hello Public").pubFunc2("Hello Public2");
});
</script>
<p class="txt">Hello Max</p>
<p class="txt">Hello Pax</p>
Ответ 5
Большинство плагинов jQuery, которые, как я вижу, пытаются выполнить это, будут использовать анонимную область действия и замыкания на ссылочные функции и переменные, уникальные для этого экземпляра. Например, используя следующий шаблон:
;(function ($) {
// your code
})(jQuery);
Между началом и концом модуля вы можете объявить любые функции, которые вы хотите. Вы не будете загрязнять глобальное пространство имен, и вы можете сохранить доступ к локальным переменным путем закрытия, что может решить многие ваши проблемы. Кроме того, не бойтесь использовать функции $.data
.