JQuery - открытые методы виджетов - PullRequest
29 голосов
/ 05 мая 2010

Если я создаю виджет 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 ]

22 голосов
/ 15 июля 2010

Виджеты jQuery UI используют метод $ .data (...) jQuery для косвенного связывания класса виджетов с элементом DOM. Предпочтительный способ вызова метода в виджете - это именно то, что было описано Максом ...

$('#list').list('publicMethod');

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

$('#list').data('list').publicMethod();

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

2 голосов
/ 15 июля 2010

Немного не по теме, я знаю, но вы можете посмотреть на jquery Entwine .

Это обеспечивает форму наследования и полиморфизма, которая допускает некоторое умное поведение с простым кодом. Похоже, это будет делать то, что вы пытаетесь сделать.

1 голос
/ 21 мая 2011

Допустим, у вас есть 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");
0 голосов
/ 09 октября 2011

Это решение основано на решении @ 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]();
            }
        }
    }
0 голосов
/ 14 июля 2010

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

$("#list").list("publicMethod");
0 голосов
/ 03 июня 2010

Как насчет этого:

$("#list").list.publicMethod

Когда вы расширяете ui.list с установленной парой ключ: значение

...