jQuery UI 拡張ウィジェット


jQuery UI の Widget Factory を使用すると、既存のウィジェットの機能を拡張するウィジェットを簡単に作成できます。このようにして、既存のウィジェットをベースにして強力なウィジェットを作成したり、既存のウィジェットの機能を微妙に調整したりすることもできます。

注: この章を学ぶ前に、ウィジェット ファクトリとは何か、そしてそれがどのように機能するかを理解する必要があります。この知識に詳しくない場合は、まず「ウィジェット ファクトリの使用方法」の章を参照してください。

ウィジェット拡張機能の作成

Widget Factory を使用してウィジェットを作成するには、ウィジェット名とプロトタイプ オブジェクトを $.widget() に渡します。次の例では、「カスタム」名前空間に「superDialog」ウィジェットを作成します。 $.widget() 传递小部件名称和一个原型对象来完成的。下面的实例是在 "custom" 命名空间中创建一个 "superDialog" 小部件。

$.widget( "custom.superDialog", {} );

为了支持扩展,$.widget() 可选性地接受作为父部件使用的小部件的构造函数。当指定一个父部件时,把它作为第二个参数进行传递,放在小部件名称后面,在小部件原型对象前面。

就像上面的实例,下面也要在 "custom" 命名空间中创建一个 "superDialog" 小部件。但是这次传递的是 jQuery UI 的 dialog(对话框)小部件 的构造函数($.ui.dialog),表示 superDialog 小部件应该使用 jQuery UI 的 dialog(对话框)小部件作为父部件。

$.widget( "custom.superDialog", $.ui.dialog, {} );

在这里,superDialog 和 dialog 两个小部件实质上是等价的,只是名称和命名空间不同而已。为了让我们新的小部件更具特点,我们可以添加一些方法到它的原型对象上。

小部件的原型对象是传递给 $.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();

当运行这段代码时,有一个问题。由于我们重载了 open()

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
 
        // Invoke the parent widget's open().
        return this._super();
    }
});
 
$( "<div>" ).superDialog();

拡張機能をサポートするために、$.widget() は親ウィジェットとして使用されるウィジェットのコンストラクターをオプションで受け入れます。親ウィジェットを指定する場合は、それを 2 番目の引数として、ウィジェット名の後、ウィジェット プロトタイプ オブジェクトの前に渡します。

上記の例と同様に、「カスタム」名前空間に「superDialog」ウィジェットも作成します。ただし、今回渡されるのは jQuery UI のダイアログ ウィジェット ($.ui.dialog) のコンストラクターであり、superDialog ウィジェットが jQuery UI のダイアログ ウィジェットを親ウィジェットとして使用する必要があることを示します。 🎜
$.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 );
    }
});
🎜ここで、superDialog と Dialog という 2 つのウィジェットは、名前と名前空間が異なることを除いて、本質的に同等です。新しいウィジェットをより特徴的なものにするために、そのプロトタイプ オブジェクトにいくつかのメソッドを追加できます。 🎜🎜ウィジェットのプロトタイプ オブジェクトは、$.widget() に渡される最後のパラメータです。これまでの例では空のオブジェクトを使用してきました。次に、このオブジェクトにメソッドを追加しましょう: 🎜
$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
$( "<div>" ).dialog();
🎜 superDialog には、テキストの色を赤に変更する red() メソッドがあります。 Widget Factory が this をウィジェットのインスタンスに自動的に設定する方法に注目してください。インスタンスで使用できるすべてのメソッドとプロパティのリストについては、Widget Factory API ドキュメントを参照してください。 🎜🎜既存のメソッドを拡張する🎜🎜 場合によっては、既存のウィジェット メソッドの動作を調整または追加する必要があります。プロトタイプ オブジェクトでオーバーライドする必要があるメソッド名としてメソッド名を指定できます。次の例では、ダイアログの open() メソッドをオーバーロードします。ダイアログ ボックスはデフォルトで開いているため、このコードが実行されると "open" がログに記録されます。 🎜
$.widget( "custom.superDialog", $.ui.dialog, {} );
 
var dialog = $( "<div>" ).superDialog();
 
// This works.
dialog.superDialog( "close" );
 
// This doesn't.
dialog.dialog( "close" );
🎜このコードを実行すると問題が発生します。 open() のデフォルトの動作をオーバーライドしたため、ダイアログは画面に表示されなくなりました。 🎜🎜 プロトタイプ オブジェクトでメソッドを使用するとき、実際には元のメソッドをオーバーロードし、プロトタイプ チェーンで新しいメソッドを使用します。 🎜

親ウィジェット メソッドを利用できるようにするために、ウィジェット ファクトリ (Widget Factory) は 2 つのメソッド - _super()_superApply() を提供します。 _super()_superApply()

使用 _super()_superApply() 来访问父部件

_super()_superApply() 在父部件中调用了同样的方法。请看下面的实例。就像上一个实例,这个实例也重载了 open() 方法来记录 "open"。然而,这次运行 _super() 是调用了 dialog(对话框)的 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();

_super()_superApply() 实际上等同于最初的 Function.prototype.call()Function.prototype.apply() 方法。因此,_super() 接受一个参数列表,_superApply() 接受一个数组作为参数。下面的实例演示了这二者之间的不同。

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

重定义小部件

jQuery UI 1.9 添加了重定义小部件的功能。因此,可以不用创建一个新的小部件,我们只需要传递 $.widget() 这样一个已有的小部件名称和构造函数即可。下面的实例在 open() 中添加了相同的记录,但不是通过创建一个新的小部件来完成的。

rrreee

通过这个方法,我们可以扩展一个已有的小部件方法,但是仍然可以使用 _super() 来访问原始的方法 - 这些都不是通过创建一个新的小部件来完成的,而是直接重定义小部件即可。

小部件(Widgets)和多态性(Polymorphism)

当在小部件扩展及它们的插件之间进行交互时候,有一点值得注意,父部件的插件不能用来调用子部件元素上的方法。下面的实例演示了这一点。

rrreee

上面的实例中,父部件的插件,dialog(),不能调用 superDialog 元素上的 close() 方法。如需了解更多调用小部件方法的知识,请查看 小部件(Widget)方法调用。

定制个性化实例

目前为止,我们看到的实例都有在小部件原型上扩展的方法。在原型上重载的方法影响了小部件的所有实例。

为了演示这一点,请看下面的实例。dialog(对话框)的两个势力都使用了相同的 open()

_super()_superApply() を使用して親ウィジェットにアクセスします

_super() _superApply () 同じメソッドが親ウィジェットで呼び出されます。以下の例を参照してください。前の例と同様に、この例でも open() メソッドをオーバーロードして "open" を記録します。ただし、今回は _super() を実行すると、ダイアログの open() が呼び出され、ダイアログが開きます。

rrreee

_super()_superApply() は、実際には元の Function.prototype.call()Function と同等です。プロトタイプ.apply() メソッド。したがって、_super() はパラメータ リストを受け入れ、_superApply() はパラメータとして配列を受け入れます。次の例は、この 2 つの違いを示しています。

rrreee

ウィジェットの再定義

jQuery UI 1.9 では、ウィジェットを再定義する機能が追加されました。したがって、新しいウィジェットを作成する代わりに、既存のウィジェット名と $.widget() のようなコンストラクターを渡すだけで済みます。次の例では、同じレコードを open() に追加しますが、新しいウィジェットを作成して追加するわけではありません。
rrreee🎜 このメソッドを使用すると、既存のウィジェット メソッドを拡張できますが、元のメソッドにアクセスするには _super() を引き続き使用します。これは新しいウィジェットを作成することでは行われません。代わりに、ウィジェットを再定義するだけです。直接。 🎜

ウィジェットとポリモーフィズム

🎜 ウィジェット拡張機能とそのプラグインの間で対話する場合、親ウィジェットのプラグインを使用してウィジェット要素のメソッドを呼び出すことはできないことに注意することが重要です。次の例はこれを示しています。 🎜rrreee🎜 上の例では、親コンポーネントのプラグインである dialog() は、superDialog 要素の close() メソッドを呼び出すことができません。ウィジェット メソッドの呼び出しの詳細については、「ウィジェット メソッドの呼び出し」を参照してください。 🎜

カスタマイズされたパーソナライズされた例

🎜 これまでに見てきた例はすべて、ウィジェット プロトタイプを拡張するメソッドを持っています。プロトタイプでオーバーロードされたメソッドは、ウィジェットのすべてのインスタンスに影響します。 🎜🎜これを示すために、以下の例を見てください。ダイアログの両側で同じ open() メソッドを使用します。 🎜rrreee🎜 ウィジェットの特定のインスタンスの動作を変更する必要がある場合があります。これを行うには、通常の JavaScript プロパティ割り当てを使用し、インスタンスへの参照を取得し、メソッドをオーバーライドする必要があります。詳細は次の例に示されています。 🎜rrreee🎜 パーソナライズされたインスタンスのオーバーロード メソッド手法は、1 回限りのカスタマイズに最適です。 🎜🎜