ウィジェットとウィジェットカラム
Ext.Widget
クラス、または 「ウィジェット」はコンポーネントによく似た軽量クラスですが、中身は、単なる
Ext.dom.Element
と関連するリスナーです。Ext.Widget
は、
Ext.Component
.
から派生しないため、ウィジェットは通常のコンポーネントとは大きく異なります。コンポーネントは、堅牢なライフサイクル管理を提供し、様々な機能性が追加されています。しかし、この機能性には「コスト」がかかります。
Ext JS 5 では、いくつかのウィジェットを提供します。次のウィジェットがあります。
- プログレスバー (
Ext.ProgressBarWidget / "progressbarwidget"
) - スライダー (
Ext.slider.Widget / "sliderwidget"
) - スパークライン (
Ext.sparkline.\*
)- Line (
"sparklineline"
) - Bar (
"sparklinebar"
) - Discrete (
"sparklinediscrete"
) - Bullet (
"sparklinebullet"
) - Pie (
"sparklinepie"
) - Box (
"sparklinebox"
) - TriState (
"sparklinetristate"
)
- Line (
このガイドで、ウィジェットの使い方や生成の仕方を説明します。さらに、最新のウィジェットカラムも紹介します。
ウィジェットを使う
普通のコンポーネントと同様、ウィジェットもコンテナの “items” に追加できます。例えば、次の様にして、ツールバーに sparkline
を追加できます。
var panel = Ext.create({ xtype: 'panel', title: 'Title', frame: true, renderTo: Ext.getBody(), width: 250, height: 150, html: 'Some text', tbar: [{ text: 'Button' }, '->', { xtype: 'sparklineline', fillColor: '#ddf', width: 100, height: 20, values: [2, 3, 0, 4, -1] }] }); |
sparklines
の場合には、サイズ (width
とheight
) を指定するか、Ext JS のレイアウトマネージャーでサイズが与えられる必要があります。その理由は、内部的の描画には、それ自身の大きさがないからです。
ウィジェットカラム
Ext JS で最も要望が多かった機能は、グリッドにより簡単にコンポーネントを追加できる事でした。あなたもそうしたいと考えていたとしたら、ウィジェットカラムをご紹介しましょう。
ウィジェットカラムによって、グリッドのセルに簡単にコンポーネントやウィジェットをレンダリングできるようになります。ウィジェットカラムを追加するのもとても簡単です。ただ、カラムの xtype
を widgetcolumn
にして、 widget
コンフィグを指定するだけです。widget
コンフィグは、各セルに生成する xtype
を指定したオブジェクトです。この xtype
には
Ext.Widget
や
Ext.Component
を指定できます。
ウィジェットカラムを利用し、グリッドに sparkline
ウィジェットを追加すると、次の図のように、様々な方法でデータを表示できます。
上図の動作するサンプルは、Kitchen Sink をご覧ください。
さて、実際に動作しているのを見てみましょう。次のサンプルでは、ウィジェットカラム付きのグリッドに挿入するするレコードの集合を持つストアを生成してます。
ウィジェットカラムはプログレスバーコンポーネントが含まれ、それは各行に追加されます。
var store = Ext.create('Ext.data.Store', { fields: ['name','progress'], data: [ { name: 'Test 1', progress: 0.10 }, { name: 'Test 2', progress: 0.23 }, { name: 'Test 3', progress: 0.86 }, { name: 'Test 4', progress: 0.31 } ] }); Ext.create({ xtype: 'grid', title: 'Widget Column Demo', store: store, columns: [{ text: 'Test Number', dataIndex: 'name', width: 100 }, { xtype: 'widgetcolumn', text: 'Progress', width: 120, dataIndex: 'progress', widget: { xtype: 'progressbarwidget', textTpl: '{value:percent}' } }], width: 220, height: 250, renderTo: Ext.getBody() }); |
“widget” コンフィグを理解する
ウィジェットカラムの widget
コンフィグは、ウィジェットの複数のインスタンスを生成するために利用されます。widget
コンフィグ内に指定される xtype
に基づいて、ウィジェットカラムは
Ext.Widget
、または
Ext.Component
から派生するオブジェクトを生成します。ウィジェットカラムは、レンダリングされたセルごとに一つのインスタンスが必要なので、既にインスタンス化されたものは指定できません。
widget
コンフィグは、コンポーネントやウィジェットの複数のインスタンスを生成するために使われますが、各インスタンスは、グリッドの特定のレコードと行と接続される必要もあります。グリッドのライフタイム中に、行に生成されたウィジェットは、「リサイクル」され、他のレコードと行に連携されます。
バッファードレンダリングの使用
ウィジェットはコンポーネントより軽量で、プログレスバーやスライダーウィジェットを利用するとグリッドの反応がよくなりますが、グリッドは多くの行がある場合には、"bufferedrenderer"
プラグインを使用するとよいでしょう。bufferedrenderer
は決まった数のコンポーネントやウィジェットを生成します。それらの項目は、レンダリングされなくなった行からリサイクルされ、新しく生成された行に追加されます。
カスタムウィジェット
Ext JS 5 は、スライダーとプログレスバーをウィジェット化したものに加え、新しい sparklines が同梱されていますが、時に自分のウィジェットを生成したいこともあるでしょう。 Ext.Component と Ext.Widget のどちらから派生するかという判断は、生成するクラスの複雑さによります。単純なコンポーネントは、コンポーネントライフサイクルやレイアウトなどを避ける事ができ、単にコンフィグプロパティを関連するエレメントにマッピングし、エレメントのイベントに反応します。
ウィジェットを生成するには、 Ext.Widget を拡張し、エレメントのテンプレートとそのリスナーを定義します。
Ext.define('MyWidget', { extend: 'Ext.Widget', // The element template - passed to Ext.Element.create() element: { reference: 'element', listeners: { click: 'onClick' }, children: [{ reference: 'innerElement', listeners: { click: 'onInnerClick' } }] }, constructor: function(config) { // テンプレートでエレメントを初期化し、initConfig()を呼び出します. this.callParent([config]); // 親クラスのコンストラクタを呼んだ後、エレメントは利用可能になり // 操作できる状態になっています。Elements の参照は、Ext.Element の // インスタンスで、各ウィジェットインスタンスに reference 名で // キャッシュされます。 }, onClick: function() { // リスナーは、このウィジェットインスタンスをそのスコープで console.log('element clicked', this); }, onInnerClick: function() { // innerElement の参照へ名前でアクセスします console.log('inner element clicked', this.innerElement); } }); |
Sencha Touch のコンポーネントを作成した事がある人には、これに馴染みがあると思います。
なぜなら、
Ext.Widget
は、Sencha Touch のExt.AbstractComponent
の改良版だからです。エレメントのテンプレートにリスナーを追加する能力は、改良点の一つですが、他にも改良点があります。詳しくは、
Ext.Widget
のドキュメントを参考にして下さい。