No.6 コンポーネントモデル
Sencha ExtJSには、コンポーネントモデルという仕組みがあります。
今回はこの仕組みついて解説致します。
コンポーネント
グリッドやパネル、ボタンなど多彩なUIを形成するのは、コンポーネントです。
コンポーネントと呼ばれるクラスは全て、Ext.Componentを継承したクラスです。
コンポーネントの中には、子要素としてコンポーネントを内包することがきるものがあり、それをコンテナーと呼びます。
このコンテナーとコンポーネントの組み合わせでUIを表現します。
Ext.create
Ext.createはクラスのインスタンスを生成するメソッドです。
第一引数にクラス名を、第二引数にその設定となるコンフィグをオブジェクトで渡すことで、インスタンスを生成します。
1 2 3 4 5 6 7 | Ext.create('Ext.panel.Panel', { title: 'Sample Panel', // パネルのタイトルを設定 renderTo: document.body, // パネルがレンダリングされる場所を設定 width: 200, // パネルのwidthを設定 height: 100 // パネルのheightを設定 // items: [] // パネルの入れ子にするコンポーネントを設定できる }); |
コンフィグで設定できる項目は各クラスによって異なります。
コンポーネントのインスタンスを生成する
明示的なインスタンス
Ext.createのメソッドを使ってコンポーネントのインスタンスを生成します。
1 2 3 4 5 6 7 8 9 10 | var win = Ext.create('Ext.window.Window', { title: 'Sample Window', width: 200, height: 100, items: [ Ext.create('Ext.button.Button', {text: 'Click!'}) ] }); win.show(); |
この方法では、Windowコンポーネントが生成されると同時に、
子要素として設定されたボタンも生成されています。
遅延インスタンス
明示的なインスタンスに対して遅延インスタンスというものがあります。
1 2 3 4 5 6 7 8 9 10 | var win = Ext.create('Ext.window.Window', { title: 'Sample Window', width: 200, height: 100, items: [{ xtype: 'button', text: 'Click!' }] }); win.show(); |
ボタンをExt.createではなく、オブジェクトで設定し、xtypeを指定しています。
xtypeとは、各コンポーネントにつけられた別名です。
このxtypeを使うと、さきほどのExt.createメソッド使って明示的にインスタンスを生成したときとは違い、
Windowコンポーネントを生成した段階ではまだ、ボタンは生成されていません。
Windowが画面に表示されるときに初めてボタンが生成されます。
このようにして、コンポーネントの生成を、必要になるまで遅らせることができます。
xtypeはAPIドキュメントで確認することができます。
コンポーネントをレンダリングする
遅延レンダリング
コンポーネントがHTMLエレメントとしてレンダリングされるのは実際に必要になった場合のみです。
さきほどのウィンドウの場合ですと、インスタンスが生成されていても、showメソッドが呼ばれるまでは
レンダリングはされません。
このようにして、リソースの節約とパフォーマンスの向上が図られています。
下記は、タブパネルのサンプルです。
1 2 3 4 5 6 7 8 9 10 11 | Ext.create('Ext.tab.Panel', { title: 'Sample Tab', width: 300, height: 200, renderTo: document.body, items: [{ title: 'Tab1' },{ title: 'Tab2' }] }); |
この場合は、Tab2のパネルは実際に表示されるまでレンダリングはされません。
xtypeの省略
上記コードでは、子コンポーネントの設定であるitemsの中でtitleしか設定していません。
コンテナーには子要素のデフォルトのxtypeが設定してあり、タブパネルの場合はpanelが設定されているので
省略するとその設定が利用されます。
明示的なレンダリング
Tab1からTab2の要素に対してなにかをしたい場合に、Tab2が生成されていないと困るといったことがあります。 そのような時は以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 | Ext.create('Ext.tab.Panel', { title: 'Sample Tab', width: 500, height: 300, deferredRender: false, renderTo: document.body, items: [{ title: 'Tab1' },{ title: 'Tab2' }] }); |
コンフィグでdeferredRenderにfalseを指定することで、内包されるコンポーネントは
遅延レンダリングされず、親のコンテナーがレンダリングされたときに即時レンダリングされます。
コンポーネントの消滅
コンポーネントは開発者が意図的に破棄しなくとも、不要になったタイミングで自動的に破棄されます。
インスタンスだけでなく、html要素も破棄されます。
コンポーネントを取得する
生成されたコンポーネントを取得するには、いくつかの方法があります。
コンポーネントクエリー
コンポーネントクエリーはExt.ComponentQueryクラスのqueryメソッドを使います。
このメソッドは条件に合致するコンポーネントの配列を取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var win = Ext.create('Ext.window.Window', { title: 'Sample Window', width: 200, height: 100, defaults: { xtype: 'button' }, items: [{ text: 'button1' },{ text: 'button2' },{ text: 'button3' }] }); win.show(); |
このようなウィンドウがあったとして、中のボタンを取得したいとします。
- xtypeで探す
1 2 | // xtypeがbuttonであるコンポーネントを取得します。 var ret = Ext.ComponentQuery.qeury('button'); |
- 親子関係を指定して探す
1 2 | // windowの子要素のbuttonコンポーネントを取得します。 var ret = Ext.ComponentQuery.qeury('window button'); |
- プロパティ値で探す
1 2 | // textがbutton1であるbuttonコンポーネントを取得します。 var ret = Ext.ComponentQuery.qeury('button[text=button1]'); |
このように、CSSセレクターのような記法によって、コンポーネントを探すことができます。
セレクターの記法については
APIドキュメント
を参照下さい。
コンポーネント内検索
コンポーネントクエリーはドキュメント全体から指定の条件のコンポーネントを探してきます。
コンポーネント自身の持つメソッドを使うことによって、対象のコンポーネントから検索することができます。
- down
downは自身の内包するコンポーネントのうち、条件に合致した最初の一つを取得します。
1 | var btn = win.down('button'); |
逆に、自身を内包するコンテナーを遡って探し、条件に合致した最初の一つを取得するupというメソッドもあります。
- query
queryはコンポーネントクエリーの起点をドキュメントではなく、そのコンポーネントにしたものです。
1 | var btns = win.query('button'); |
他にも、childやnextNodeなどのメソッドが用意されています。
今回はここまで。
次回は今回学んだコンポーネントたちをどのように配置するかを決めるレイアウトモデルについてです。
お楽しみに!