jQuery UI ウィジェット・ファクトリー(Widget Factory)を使ってウィジェットを拡張する
jQuery UI のウィジェット・ファクトリー(Widget Factory)を使用すると、既存のウィジェットの機能を拡張するウィジェットの作成がより簡単になります。これにより、既存の機能をベースに強力なウィジェットを作成したり、既存のウィジェットの機能を微調整したりできます。
注意:この章を学習する前に、ウィジェット・ファクトリー(Widget Factory)とは何か、そしてそれがどのように機能するかを理解している必要があります。これらの知識にまだ慣れていない場合は、最初に次の項を参照してください。ウィジェット・ファクトリー(Widget Factory)の使用方法の章。
ウィジェット拡張の作成
ウィジェット・ファクトリー(Widget Factory)でウィジェットを作成するには、$.widget()ウィジェット名とプロトタイプオブジェクトを渡します。次の例では、"custom" 名前空間に "superDialog" ウィジェットを作成します。
$.widget( "custom.superDialog", {} );
拡張をサポートするために、$.widget()ウィジェット・ファクトリーは、親ウィジェットとして使用するウィジェットのコンストラクターをオプションで受け付けます。親ウィジェットを指定する場合、ウィジェット名の後、ウィジェットのプロトタイプオブジェクトの前に、第2引数として渡します。
上記の例と同様に、次も "custom" 名前空間に "superDialog" ウィジェットを作成します。ただし、今回は渡すのはjQuery UI の dialog(ダイアログ)ウィジェットのコンストラクター($.ui.dialog)。これは、superDialog ウィジェットが親ウィジェットとして jQuery UI の dialog(ダイアログ)ウィジェットを使用すべきことを示しています。
$.widget( "custom.superDialog", $.ui.dialog, {} );
ここでは、superDialog と dialog の2つのウィジェットは実質的に同等であり、名前と名前空間が異なるだけです。新しいウィジェットに独自の特徴を持たせるために、そのプロトタイプオブジェクトにいくつかのメソッドを追加できます。
ウィジェットのプロトタイプオブジェクトは、$.widget()渡される最後の引数です。これまでのところ、この例では空のオブジェクトを使用しています。では、このオブジェクトにメソッドを追加してみましょう。
$.widget( "custom.superDialog", $.ui.dialog, {
red: function() {
this.element.css( "color", "red" );
}
});
// Create a new <div>, convert it into a superDialog, and call the red() method.
$( "<div>I am red</div>" )
.superDialog()
.superDialog( "red" );
ここでsuperDialogにはred()メソッドがあります。これによりテキストの色が赤に変更されます。ウィジェット・ファクトリー(Widget Factory)がどのように自動的にthisをウィジェットのインスタンスオブジェクトとして設定するかに注意してください。インスタンス上で利用可能なすべてのメソッドとプロパティの一覧については、ウィジェット・ファクトリー(Widget Factory) API ドキュメントを参照してください。。
既存のメソッドを拡張する
場合によっては、既存のウィジェットメソッドの動作を調整または追加する必要があります。プロトタイプオブジェクト上でオーバーライドしたいメソッド名を指定できます。次の例では、dialog(ダイアログ)のopen()メソッドをオーバーライドします。ダイアログはデフォルトで開いているため、このコードを実行すると、"open"が記録されます。
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
}
});
// Create a new <div>, and convert it into a superDialog.
$( "<div>" ).superDialog();
このコードを実行すると、問題が1つあります。私たちはopen()のデフォルトの動作をオーバーライドしたため、dialog(ダイアログ)は画面に表示されなくなります。
プロトタイプオブジェクト上でメソッドを使用するとき、実際には元のメソッドをオーバーライドし、プロトタイプチェーン内で新しいメソッドを使用しています。
親ウィジェットのメソッドを利用可能にするために、ウィジェット・ファクトリー(Widget Factory)は2つのメソッドを提供します -_super()と_superApply()。
使用_super()と_superApply()親ウィジェットにアクセスする
_super()と_superApply()親ウィジェット内で同じメソッドを呼び出します。次の例を見てください。前の例と同様に、この例でもopen()メソッドをオーバーライドして"open"を記録します。ただし、今回は_super()呼び出しているのは dialog(ダイアログ)のopen()メソッドであり、ダイアログを開きます。
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
// Invoke the parent widget's open().
return this._super();
}
});
$( "<div>" ).superDialog();
_super()と_superApply()実際には元のFunction.prototype.call()とFunction.prototype.apply()メソッドと同等です。したがって、_super()はパラメータリストを受け取り、_superApply()は配列をパラメータとして受け取ります。次の例は、この2つの違いを示しています。
$.widget( "custom.superDialog", $.ui.dialog, {
_setOption: function( key, value ) {
// Both invoke dialog's setOption() method. _super() requires the arguments
// be passed as an argument list, _superApply() as a single array.
this._super( key, value );
this._superApply( arguments );
}
});
ウィジェットの再定義
jQuery UI 1.9 では、ウィジェットを再定義する機能が追加されました。したがって、新しいウィジェットを作成する必要はなく、私たちは単に$.widget()既存のウィジェット名とコンストラクターを渡すだけで十分です。次の例では、open()に同じ記録を追加していますが、新しいウィジェットを作成するわけではありません。
$.widget( "ui.dialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
$( "<div>" ).dialog();
この方法により、既存のウィジェットメソッドを拡張できますが、引き続き_super()を使用して元のメソッドにアクセスできます - これらはすべて新しいウィジェットを作成するのではなく、ウィジェットを直接再定義することによって行われます。
ウィジェットとポリモーフィズム
ウィジェット拡張とそれらのプラグインとの間で相互作用する際、注意すべき点が1つあります。親ウィジェットのプラグインは、子ウィジェットの要素上のメソッドを呼び出すために使用することはできません。次の例はこれを示しています。
$.widget( "custom.superDialog", $.ui.dialog, {} );
var dialog = $( "<div>" ).superDialog();
// This works.
dialog.superDialog( "close" );
// This doesn't.
dialog.dialog( "close" );
上記の例では、親ウィジェットのプラグイン、dialog()は、superDialog 要素上のclose()メソッドを呼び出すことはできません。ウィジェットメソッドの呼び出しについて詳しくは、ウィジェット(Widget)メソッドの呼び出しを参照してください。。
個別インスタンスのカスタマイズ
これまでのところ、例ではウィジェットのプロトタイプ上でメソッドを拡張してきました。プロトタイプ上でオーバーライドされたメソッドは、ウィジェットのすべてのインスタンスに影響を与えます。
これを示すために、次の例を見てください。dialog(ダイアログ)の2つのインスタンスは両方とも同じopen()メソッドを使用しています。
$.widget( "ui.dialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
// Create two dialogs, both use the same open(), therefore "open" is logged twice.
$( "<div>" ).dialog();
$( "<div>" ).dialog();
場合によっては、ウィジェットの特定のインスタンスの動作だけを変更する必要があります。これを行うには、通常の JavaScript のプロパティ代入を使用してインスタンスへの参照を取得し、そのメソッドをオーバーライドします。具体的には次の例のようになります。
var dialogInstance = $( "<div>" )
.dialog()
// Retrieve the dialog's instance and store it.
.data( "ui-dialog" );
// Override the close() method for this dialog
dialogInstance.close = function() {
console.log( "close" );
};
// Create a second dialog
$( "<div>" ).dialog();
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );
個別化されたインスタンスのメソッドをオーバーライドする技法は、一度限りの完璧なカスタマイズです。
その他の拡張