Sencha Touch を使った Web アプリ開発では HTML を直接記述せず、組み立てたコンポーネントが自動的に HTML を出力します。コンポーネントがどのような HTML を出力するかはブラックボックスのようですが、実は elementConfig という定義情報を元にしています。今回は、カスタムコンポーネントを作成する際に便利な elementConfig の拡張方法について紹介します。
Problem:
コンポーネントが出力する HTML 要素を自由に指定したい。
Solution:
template プロパティで HTML の出力情報を定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
Ext.define('sample.view.MyComp', { extend: 'Ext.Component', xtype: 'mycomp', template: [ { tag: 'div', // <div></div> class: 'left' // class="left" }, { tag: 'div', class: 'right', children: [ // 子要素 { tag: 'span', // <span></span> text: 'foo' // foo (innerText) }, { tag: 'span', text: 'bar', hidden: true // display: none; } ] }, { tag: 'input', // <input></input> name: 'baz', // name="baz" value: 'foobar' // value="foobar" } ] }); |
このコンポーネントは以下のように表示されます。
出力される HTML 要素は以下です。
1 2 3 4 5 6 7 8 |
<div class="x-unsized" id="ext-mycomp-1"> <div class="left"></div> <div class="right"> <span>foo</span> <span style="display: none;">bar</span> </div> <input name="baz" value="foobar"/> </div> |
Discussion:
一番外側はコンポーネントとして最低限必要な div 要素です。その中身は template で指定した内容を元に HTML 要素が出力されています。
コンポーネントの HTML 要素は AbstractComponent.js の initElement メソッド内で生成されます。ここで getElementConfig で取得した情報を元に Ext.Element.create メソッドを使って要素を生成しているのですが、その定義情報を拡張する手段として用意されているのが template プロパティです。
既に template プロパティが定義されているコンポーネントを継承している場合、template プロパティを設定すると継承元の定義を上書きしてしまうので要注意です。その場合は getTemplate メソッドをオーバーライドする方法で指定した方がよいでしょう。
1 2 3 4 5 6 7 8 |
getTemplate: function() { var template = this.callParent(arguments); template.push({ tag: 'div', // <div></div> class: 'hoge' // class="left" }); return template; } |
ただ、 getElementConfig メソッドを独自に上書きしているコンポーネントがあって、templete プロパティが無視されてしまうことがあります。container コンポーネントや toolbar コンポーネントなどが、それに該当します。。その場合は、仕方ないので、getElementConfig メソッドを直接オーバーライドして追加で定義を足す必要があります。
タグの属性は、どのようなものでも指定することができます。詳しくは Ext.dom.Element クラスの create メソッドを参照して下さい。
また reference という便利なプロパティがあります。reference プロパティを使えば、コンポーネントから要素に簡単にアクセスできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Ext.define('sample.view.MyComp', { extend: 'Ext.Component', xtype: 'mycomp', template: [ { tag: 'input', value: 'hello!', reference: 'hello' } ], initialize: function() { var value = this.hello.getValue(); // 'hello' 要素にアクセス alert(value); // => hello! } }); |
コンポーネントが出力する HTML を制御できると、Sencha Touch が身近に感じてきますね。以上、カスタムコンポーネントを作る時などに便利な elementConfig の拡張方法でした。
最近のコメント