Доступ к .selector в виджете пользовательского интерфейса jQuery

#jquery #jquery-ui

#jquery #jquery-пользовательский интерфейс

Вопрос:

Я работаю над плагином, используя фабрику виджетов пользовательского интерфейса. С помощью базового плагина jQuery я могу получить доступ к используемому селектору, выполнив что-то вроде этого…

 $.fn.pluginname = function(){
    var thisWorks = this.selector;
};
  

Однако, когда я использую фабрику виджетов, доступ к выбранному элементу осуществляется через свойство ‘this.element’, а ‘this.element.selector’ работает не так, как в моем первом примере. У кого-нибудь есть хороший способ обойти это? Я просматриваю исходный код widget factory на GitHub, но пока ничего не смог найти.

Ответ №1:

Хитрость заключается в том, что после того, как widget factory завершит создание вашего виджета, после этого это, по сути, просто обычный плагин. Это означает, что вы можете еще больше расширить его.

Идея состоит в том, чтобы сохранить исходную функцию, заменить ее пользовательской функцией и заставить ее пропускать селектор. Этот код может находиться где угодно после фабрики виджетов и до того, как вы используете свой объект в первый раз. Просто поместите его в файл вашего плагина после вызова $.widget() .

Имя виджета в этом примере — test .

 // Save the original factory function in a variable
var testFactory = $.fn.test;

// Replace the function with our own implementation
$.fn.test = function(obj){
    // Add the selector property to the options
    $.extend(obj, { selector: this.selector });

    // Run the original factory function with proper context and arguments
    return testFactory.apply(this,arguments);
};
  

Это гарантирует, что this.selector передается как именованный параметр. Теперь вы можете получить к нему доступ в любом месте вашей фабрики, обратившись this.options.selector .

В качестве дополнительного плюса нам не нужно было взламывать какой-либо код пользовательского интерфейса jQuery.

Комментарии:

1. Фантастика. Никогда не думал делать это таким образом. Мне нужно поиграть с аргументами для того, что я делаю, но, похоже, это будет работать просто отлично. Спасибо!

2. Как бы мне это сделать, если я просто изменяю (duckpunching) один из методов виджетов, например метод close всплывающей подсказки, и мне нужно получить доступ к исходному селектору. Возможно ли это? Вот нерабочий пример: jsfiddle.net/corydorning/9grH5

3. Смог разобраться в этом, используя вышеприведенные принципы, хотя мне пришлось перезаписать параметры прототипа для виджета, который я исправлял. Суть здесь: gist.github.com/4445666

Ответ №2:

Всего пара моих центов… вот рабочий пример JSFiddle, основанный на ответе DarthJDG… Возможно, кому-то это понадобится.

 $(function () {
    $.widget("test.testwidget", {
        _create: function () {
            this.element.text('Selector: '   this.options.selector)
        },
    });
}(jQuery));

// Save the original factory function in a variable
var testFactory = $.fn.testwidget;

// Replace the function with our own implementation
$.fn.testwidget = function(obj){
    // Add the selector property to the options
    $.extend(obj, { selector: this.selector });

    // Run the original factory function with proper context and arguments
    return testFactory.apply(this,arguments);
};

$(document).ready(function() {
    $('#test').testwidget({});
    $('.test').testwidget({});
});
  

Ответ №3:

Также возможно просто использовать

 this.selector =  '#' this.element.attr('id');
  

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