レイアウトとコンテナー
レイアウトシステムは、Ext JS のとても強力な部分の一つです。アプリケーション内の各 コンポーネント のサイズと位置を管理します。このガイドは、レイアウトを使い始めるための、基本的なところを説明をします。
コンテナー
Ext JS アプリケーションの UI は コンポーネント (詳しい説明は Components Guide をご覧下さい。 コンテナー は、他のコンポーネントを含むことができる、特別なコンポーネントです) で出来ています。 通常の Ext JS アプリケーションは、いくつかのネストされたコンポーネントのレイヤーでできています。
最もよく使われるコンテナーは Panel. です。さて、Panel がコンテナーとして、どのように他のコンポーネントを配置するかを見てみましょう。
Ext.create('Ext.panel.Panel', { renderTo: Ext.getBody(), width: 400, height: 300, title: 'Container Panel', items: [ { xtype: 'panel', title: 'Child Panel 1', height: 100, width: '75%' }, { xtype: 'panel', title: 'Child Panel 2', height: 100, width: '75%' } ] }); |
ドキュメントのボディに描画するパネルを生成し、 items コンフィグを使って、コンテナーの Panel に二つの子供の Panel を追加しました。
レイアウト
各コンテナーには、子コンポーネントのサイズと位置を管理する、 レイアウトがあります。 このセクションでは、コンテナーに特定のレイアウトを指定する方法と、レイアウトシステムがどうやって全てを同期し続けるかについて見ていきます。
レイアウトを使う
前出のサンプルでは、コンテナーとなる Panel. のレイアウトを指定しませんでした。 DOM の普通のブロック要素のように、子供の Panel は順番に配置されている事に注目してください。 この理由は、全てのコンテナーのデフォルトレイアウトは Auto レイアウトになっているからです。 Auto レイアウトは子要素に特別な位置やサイズのルールを指定しません。 それでは、例えば二つの子 Panel を隣同士に配置して、両方ともコンテナーの幅の50%ずつを使うように指定したいとしましょう。その場合はコンテナーに layout コンフィグを設定するだけで、 Column レイアウト を使うことができます。
Ext.create('Ext.panel.Panel', { renderTo: Ext.getBody(), width: 400, height: 200, title: 'Container Panel', layout: 'column', items: [ { xtype: 'panel', title: 'Child Panel 1', height: 100, columnWidth: 0.5 }, { xtype: 'panel', title: 'Child Panel 2', height: 100, columnWidth: 0.5 } ] }); |
Ext JS にはフルセットのレイアウトがついてきますので、思いつく限りのレイアウトの種類に対応します。 レイアウトブラウザ Kitchen Sink のレイアウトのセクション をご覧になると、レイアウトの動きの違いが分かります。
レイアウトシステムの動作
コンテナーのレイアウトは、コンテナーの子要素の初期サイズと位置に対する責任があります。
内部的には、フレームワークはコンテナーの
doLayout
メソッドを呼び出し、それがコンテナーの子要素供の適切な位置やサイズを全て演算するようにレイアウトを起動し、DOMをアップデートします。
doLayout
メソッドは完全に再帰的で、コンテナーの子要素供についても全て doLayout
メソッドが呼び出されます。
これがコンポーネント階層の一番下につくまで続きます。
通常はアプリケーションから doLayout()
を呼び出す必要はありません。フレームワークがそれを処理します。
コンテナーがリサイズ,された場合、または子供コンポーネントアイテムが追加されたり、削除された場合に、re-layout がトリガーされます。
通常は、フレームワークにレイアウトのアップデートを管理を任せますが、
フレームワークの自動レイアウトを停止して、複数の操作をまとめて処理して、完成した後に手動でレイアウトをトリガーするようにしたいこともあります。
これを行うには、通常だとレイアウトをトリガーする操作 (例えば項目の追加や削除) を行っている間、レイアウトを行わないように、コンテナーの
suspendLayout
フラグを使います。全てが完了したら、suspendLayout
フラグをオフにして、コンテナーの doLayout
メソッドを手動で呼び出します。
var containerPanel = Ext.create('Ext.panel.Panel', { renderTo: Ext.getBody(), width: 400, height: 200, title: 'Container Panel', layout: 'column', suspendLayout: true // レイアウトをトリガーする操作を行う時に }); // 自動レイアウトを中断する // 二つの子アイテムを追加する。add() に配列を渡せば、両方同時に追加できますが // なにかの理由で別々に追加する必要があるとしましょう containerPanel.add({ xtype: 'panel', title: 'Child Panel 1', height: 100, columnWidth: 0.5 }); containerPanel.add({ xtype: 'panel', title: 'Child Panel 2', height: 100, columnWidth: 0.5 }); // suspendLayout フラグをオフにする containerPanel.suspendLayout = false; // レイアウトをトリガーする containerPanel.doLayout(); |
コンポーネントレイアウト
コンテナーのレイアウトが、コンテナーがコンポーネント アイテムのサイズと位置を定義するように、コンポーネントにもレイアウトがあり、内部の子アイテムの位置やサイズを定義します。 コンポーネントレイアウトは componentLayout コンフィグオプションを使って構成します。
提供されているコンポーネントには、独自のレイアウトマネージャーが付いているので、カスタムコンポーネントを作るのでない限り、この構成は必要ありません。 ほとんどのコンポーネントは Auto Layout を使いますが、より複雑なコンポーネントはカスタムコンポーネント レイアウトが必要となります(例えば、 Panel には、ヘッダー、フッター、ツールバーがあります)。