プラグインのインフラストラクチャとしてのjQuery UI

はじめに



jQuery UIは、一連の定義済みウィジェットとして最もよく知られています。 私の意見では、それらの主な利点は一貫したAPIです。各ウィジェットは同じ方法で管理されます。 2番目の利点は、状態を保存することです。要素でウィジェットを再ハングすると、結果はウィジェットの既存のインスタンスになります。

しかし、jQuery UIは単なるウィンドウとタブのセットではありません(誰もがお気に入りではありません)。 これは、独自のウィジェットを作成するための完全なインフラストラクチャです。便利な一貫性のあるAPI、状態ストレージ、および継承の可能性を備えています。 奇妙なことに、これは多くの人にとってのニュースであり、その結果、この記事が登場しました-ちょうど数か月前に私にとってニュースであったように。





叙情的な余談



時間と場所を無駄にしないために、コード内のすべての場所でwindow。$ == window.jQuery、undefinedが破損していないこと、jQuery、jQueryのみ、jQueryのみを接続し、すべての広告が次のようにラップされていることがわかりますこれの:

( function ($) {

//

})(jQuery)


* This source code was highlighted with Source Code Highlighter .






また、読者はjQueryに精通しており、少なくともjQuery UIからドキュメントを読むことも理解されています。



マジック$ .widget



すべての魔法は$.widget



メソッドにあります。 2(または3-継承の場合)パラメーターを取ります。 公式には、このメソッドは「ウィジェットファクトリ」と呼ばれます。

最初のパラメーターは文字列で、名前空間とウィジェット名自体がドットで区切られて含まれています。 たとえば、 "my.myWidget"



。 名前空間が必要です。 ネストはサポートされていません。 2番目のパラメーターはオブジェクトリテラルで、実際にはウィジェットを説明します。

$.widget( "my.myWidget" , {

options: {

greetings: "Hello"

},

_create: function () {

this .element.html( this .options.greetings);

}

})


* This source code was highlighted with Source Code Highlighter .






_create



という名前のフィールドにある関数は、コンストラクターとして機能し、ウィジェットインスタンスの作成時に呼び出されます。 このインスタンスはthisによって示されthis





this.element



は、ウィジェットがハングしている要素です。 これは常にコレクションではなく単一のアイテムです(通常のプラグインの場合)。 ウィジェットを複数の要素を含むjQueryオブジェクトにアタッチすると、できるだけ多くのインスタンスが作成されます。

options



フィールドには、ウィジェットのデフォルト設定が保存されます。 このフィールドは継承されるため、明示的に宣言しなくても、常にウィジェット内にあります。

ウィジェットを呼び出すときにオブジェクトを渡すと、 _create



呼び出す前に、渡されたオブジェクトがデフォルト設定で「染色」されます( $.merge



メソッドを使用)。

setOption



メソッドは、設定を操作します。

$.widget( "my.myWidget" , {

options: {

greetings: "Hello"

},

_create: function () {

this ._render();

},

_render: function () {

this .element.html( this .options.greetings);

},

setOption: function (key, value) {

if (value != undefined) {

this .options[key] = value;

this ._render();

return this ;

}

else {

return this .options[key];

}

}

})


* This source code was highlighted with Source Code Highlighter .






これは、標準のウィジェットと同じ方法で使用されます。

var mw = $( '.mywidget' ).myWidget({greeting: 'Hi there!' })

console.log(mw.myWidget( 'option' , 'greeting' )); // 'Hi there!'

mw.myWidget( 'option' , 'greeting' , 'O HAI CAN I HAZ CHEEZBURGER?' );


* This source code was highlighted with Source Code Highlighter .








プライベートおよびパブリックメソッド



ウィジェットメソッドには、設定を参照するのとほぼ同じ方法でアクセスできます。

$.widget( "my.myWidget" , {

options: {

greetings: "Hello"

},

_create: function() {

this ._render();

},

_render: function() {

this .element.html( this .options.greetings);

},

sayHello: function(saying) {

alert(saying);

},

_setOption: function(key, value ) {

if (arguments.length == 1) {

this .options[key] = value ;

this ._render();

return this ;

}

else {

return this .options[key];

}

}

})

// …

mw.myWidget( "sayHello" , 42);


* This source code was highlighted with Source Code Highlighter .






ただし、このためには、このメソッドはパブリックでなければなりません。 UIプラグインのパラダイムでメソッドをパブリックにする方法は? 簡単です。ウィジェットエンジンは、名前がアンダースコアで始まらないパブリックメソッドを考慮します。 他のすべてのメソッドはプライベートです。 関数ではないウィジェットフィールドは常にプライベートのみです。

これは、もちろん、パブリックメソッドとプライベートメソッドの完全な意味ではありませんが、それらのエミュレーションは、アクセスを区別するのに十分です。



コールバック



実際、これらはウィジェット内のユーザーイベントにバインドするための単なるショートカットです。 これらは、設定と同じ方法でウィジェットに転送されます。

$.widget( "my.myWidget" , {

options: {

greetings: "Hello"

},

_create: function () {

this ._render();

},

_render: function () {

this .element.html( this .options.greetings);

this ._trigger( "onAfterRender" , null , {theAnswer: 42})

}

})

// …

var mw = $( ".mywidget" ).myWidget(

{

greeting: "Hi there!" ,

onAfterRender: function (evt, data) {

console.log(data.theAnswer)

}

})




* This source code was highlighted with Source Code Highlighter .






これは、次のような古き.bind



と同等です。

mw.bind( 'onAfterRender.myWidget' , function (evt, data) {console.log(data.theAnswer)})

* This source code was highlighted with Source Code Highlighter .








デストラクタ



箱から出てくるウィジェットは、多くのマークアップを生成する傾向があります。 これが良いか悪いかは議論の余地のある問題です。 しかし、これは、一部はウィジェットインスタンスへのリンクがDOM要素のexpando属性に書き込まれるためです。一部は、ウィジェットを破棄するときにデストラクタを呼び出す必要があります。

destroyと呼ばれるメソッドは、デストラクタとして呼び出されます。 残念ながら、常に明示的に呼び出す必要があります。 完全な幸福のために、次の呼び出しはデストラクタ内になければなりません:

$.Widget.prototype.destroy.call( this );

* This source code was highlighted with Source Code Highlighter .








継承



最もおいしいものの1つですが、実際には情報はありません。

2番目の引数が他のウィジェットAに渡された場合(この場合のウィジェットは3番目の引数です)、新しいウィジェットBはその子孫になります。

アプリケーションに多くのダイアログボックスがあり、すべてがモーダルであるとします。 ただし、Escで閉じないでください。 毎回書く気はありません:

$( '.dialog' ).dialog({

modal: true ,

closeOnEscape: false ,

// … ,

// …

})


* This source code was highlighted with Source Code Highlighter .








標準ダイアログから継承して、デフォルト設定を再定義できます。

$.widget( "my.mydlg" , $.ui.dialog, {

options: {

modal: true ,

closeOnEscape: false ,

},

_create: function() {

$.ui.dialog.prototype._create.call( this );

}

})


* This source code was highlighted with Source Code Highlighter .






次に、コード全体で.dialog呼び出しを.mydlgに置き換え、重複を減らします。 残念ながら、明示的に祖先を指定し、そのコンストラクタを手動で呼び出す必要があります。



おわりに



UIウィジェットはコードを変調する良い方法のように思えます。 中小規模のプロジェクトでは、それら自体が十分なアプリケーションインフラストラクチャを提供できます。

この場合、かなり重いjQueryUIであるコアコンポーネント全体をドラッグする必要はありません。

このウィジェットエンジンの基礎となるパターンはブリッジと呼ばれます(もちろん、 $.widget



メソッドはファクトリーです)。 ファイルで$ .widgetメソッドを完了すると、マークアップから設定を読み取り、重要な要素を見つけ、自動的に階層構造に整理されるウィジェットを取得できます。 しかし、これは明らかに別の記事のトピックです。



All Articles