JQuery - открытые методы виджетов
Если я создаю виджет JQuery (пример кода ниже), а затем определяю "публичный" метод, есть ли другой способ вызова метода, кроме использования следующей формы?
$("#list").list("publicMethod");
Я хотел бы создать серию виджетов, которые все определяют одни и те же методы (в основном реализуя один и тот же интерфейс), и иметь возможность вызывать метод, не зная ничего о том, для какого виджета я сейчас вызываю метод. В текущей форме мне нужно знать, что я выполняю метод в виджете "список".
Ниже приведен пример создания виджета методом public.
(function($) {
var items = [];
var itemFocusIdx = 0;
$.widget("ui.list", {
// Standard stuff
options : { ... },
_create : function() { ... },
destroy : function() { ... },
// My Public Methods
publicMethod : function() { ... }
...
});
}(jQuery));
6 ответов
Виджеты пользовательского интерфейса jQuery используют метод $.data (...) jQuery, чтобы косвенно связать класс виджета с элементом DOM. Предпочтительный способ вызова метода в виджете - это именно то, что было описано Максом...
$('#list').list('publicMethod');
... но если вы хотите указать возвращаемое значение, вам повезет, назвав его так, используя метод data:
$('#list').data('list').publicMethod();
Однако при использовании второго способа обходятся все шаблоны виджетов пользовательского интерфейса jQuery, и, по возможности, его следует избегать, если это возможно.
Немного не по теме, я знаю, но вы можете посмотреть на jquery Entwine.
Это обеспечивает форму наследования и полиморфизма, которая допускает некоторое умное поведение с простым кодом. Похоже, это будет делать то, что вы пытаетесь сделать.
Допустим, у вас есть list
, list2
, а также superList
... давайте вызовем publicMethod для каждого из них:
$.fn.callWidgetMethod = function(method) {
var $this = this,
args = Array.prototype.slice.call(arguments, 1);
// loop though the data and check each piece of data to
// see if it has the method
$.each(this.data(), function(key, val) {
if ($.isFunction(val[method])) {
$this[key].apply($this, args);
// break out of the loop
return false;
}
});
}
$("#some-element").list();
$("#another-element").list2();
$("#hydrogen").superList();
$("#some-element").callWidgetMethod("publicMethod");
$("#another-element").callWidgetMethod("publicMethod");
$("#hydrogen").callWidgetMethod("publicMethod");
Это решение вдохновлено решением @Jiaaro, но мне нужно было возвращаемое значение, и оно было реализовано как функция JavaScript, а не как расширение jQuery:
var invokeWidgetMethod = function(methodName, widgetElem)
{
var $widgetElem = $(widgetElem),
widgetData = $widgetElem.data(),
dataName,
dataObject;
for(dataName in widgetData)
{
dataObject = widgetData[dataName];
if ($.isFunction(dataObject[methodName])) {
return dataObject[methodName]();
}
}
}
Как насчет этого:
$("#list").list.publicMethod
Поскольку вы расширяете ui.list с установленной парой ключ: значение