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));
jQuery UIウィジェットは、jQueryの$ .data(...)メソッドを使用して、ウィジェットクラスをDOM要素に間接的に関連付けます。ウィジェットでメソッドを呼び出すための好ましい方法は、Max ...によって記述されたものとまったく同じです。
$('#list').list('publicMethod');
...しかし、戻り値をフィールド化する場合は、dataメソッドを介してこのように呼び出す方が幸運です。
$('#list').data('list').publicMethod();
ただし、2番目の方法を使用すると、jQuery UIウィジェットパターン全体が回避されるため、可能であれば回避する必要があります。
少しトピックから外れていることはわかっていますが、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のソリューションに触発されていますが、戻り値が必要であり、jQueryを拡張するのではなくJavaScript関数として実装しました。
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]();
}
}
}