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

Попробуй это:

$("#list").list("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 с установленной парой ключ: значение

Другие вопросы по тегам