Sencha Touch と ExtJS
Sencha Advent Calendar 2013 7日目です。
最近、私が Sencha に詳しいと言うことで、とある仕事で Sencha を使うことになりました。しかし、Sencha でも ExtJS の方。私が得意なのは Touch なんだけど。。。最近の ExtJS は全く知らない(汗
とはいえ、ExtJS4 になって Ext.define とか MVC とか Sencha cmd とか似たような感じっぽい。というよりむしろ Touch の元になったものなので、何とかなるだろうと始めてみました。最初は使うコンポーネントが違うくらいだろうと思ったのですが、使い出していると意外と細かいところで違うものなんだなぁ、と気がつきました。
というわけで、今日のテーマは「ここが違うよ!ExtJS と Sencha Touch」
Sencha Touch と ExtJS の両方をある程度知っている人にしか分からない、細かすぎて伝わらないネタです。
configが違う
Sencha Touchでは、Ext.define で渡すコンフィグオブジェクトに、config という名前のプロパティオブジェクトを付けると、それは特殊なconfigプロパティとして認識されます。例えば、config オブジェクトに name というプロパティをセットすると、自動的に updateName や applyName というメソッドが追加されます。それらをオーバーライドすることで、各プロパティをセットしたときのフックが定義できます。
ExtJSでも config は使えるのですが、各種コンポーネントがこの作りに対応していません。Touchのコンポーネントは基本的にこのconfigを使って作られているため、プロパティのフックが簡単に行えるのですが、ExtJSではできません。そのうち対応してくれると嬉しいなぁ。
コントローラーが違う
ExtJSも4からMVCアーキテクチャが導入され、Controllerクラスが使えます。ただし、これも Touch のController と少し違います。
ExtJSのControllerの定義は次のような感じ。
Ext.define('MyApp.controller.Users', { extend: 'Ext.app.Controller', refs: [{ ref: 'list', selector: 'grid' }], init: function() { this.control({ 'button': { click: this.refreshGrid } }); }, refreshGrid: function() { this.getList().store.load(); } });
対して、Touchのコントローラーはこんな感じ。
Ext.define('MyApp.controller.Main', { extend: 'Ext.app.Controller', config: { control: { loginButton: { tap: 'doLogin' }, 'button[action=logout]': { tap: 'doLogout' } }, refs: { loginButton: 'button[action=login]' } }, doLogin: function() { //called whenever the Login button is tapped }, doLogout: function() { //called whenever any Button with action=logout is tapped } });
refs で コンポーネントをComponentQuery で指定するのはほとんど同じです。しかし、control定義が全然違う。少し驚きですね。また、ExtJS の control定義では、refs で定義した名前が使えない!!これにはやられました。Touchから入った人ははまるポイントではないでしょうか。(ってそんな人いるのか・・?)
bootloaderが違う
Sencha Cmdで、sencha generate app でアプリケーションを作るときに、sdkパスを Touch か ExtJSを切り替えるだけで、どっちのアプリケーションでも簡単に作れます。index.html も作ってくれるのですが、これが読み込む JS がまた違う。
Touch のほうは、microloader というのを読み込んで、それがアプリケーションを読み込んでくれます。この microloader を development か production を切り替えるだけで開発と本番を切り替えられます。次のような index.htmlが作られます。
<!DOCTYPE HTML> <html manifest="" lang="en-US"> <head> <meta charset="UTF-8"> <title>Sample</title> <style type="text/css">/* 略 */</style> <script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script> </head> <body> <div id="appLoadingIndicator"> <div></div> <div></div> <div></div> </div> </body> </html>
ExtJSは全然違います。次は ExtJS の index.html です。
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Sample</title> <!-- <x-compile> --> <!-- <x-bootstrap> --> <link rel="stylesheet" href="bootstrap.css"> <script src="ext/ext-dev.js"></script> <script src="bootstrap.js"></script> <!-- </x-bootstrap> --> <script src="app.js"></script> <!-- </x-compile> --> </head> <body></body> </html>
bootstrap という 似たような物があるのですが、microloaderとはまた別の物。これが結構くせ者で、ビルドする度にパスが変わったりで慣れるまで苦労しました。実は ExtJS のテンプレートの方にも .sencha/app/microloader/ があります。これが使えるのか検証してないですが、使えるようになってくれると嬉しい。