ちょっとSencha Touchで遊んでて、タイマーの操作ってどう書くのがいいのかなーと思って試してみました。
具体的にいうと、Sencha TouchのAPIにExt.util.DelayedTaskというクラスがあって、setTimeoutとどう違うのかな、と。
次のようにsenchaコマンドで生成したアプリケーションをベースにすることを前提にしています。
sencha app create -n Watch -p /hoge/watch
画面はこんな感じで用意します。
https://gist.github.com/3883758#file_app_view_main.js
んで、コントローラなんですけど、setTimeoutを使ったものがこれ。
https://gist.github.com/3883758#file_app_controller_watch_controller1.js
DelayedTaskを使ったものがこれ。
https://gist.github.com/3883758#file_app_controller_watch_controller2.js
setTimeoutを使うときには、呼び出された関数内でのthisはコントローラオブジェクトをあらわさないので、改めてコントローラオブジェクトを渡してやる必要があります。そんで、それを_thisとか引数として受け取って次のように書きます。
count: function(_this){ if(!_this.getRunning()) return; var c = _this.getCounter(); var min = c / 60 | 0;//整数化 var sec = c % 60; _this.getTimeLabel().setHtml(min + ":" + sec); _this.setCounter(c + 1); setTimeout(_this.count, 1000, _this); }
でも、なんか他と統一感なくてイヤな感じ。
DelayedTaskだと、スコープとしてthisになる値を指定できるので、次のように書けます。
count: function(){ if(!this.getRunning()) return; var c = this.getCounter(); var min = c / 60 | 0;//整数化 if(min < 10) min = "0" + min; var sec = c % 60; if(sec < 10) sec = "0" + sec; this.getTimeLabel().setHtml(min + ":" + sec); this.setCounter(c + 1); var task = Ext.create('Ext.util.DelayedTask', this.count, this); task.delay(1000); }
DelayedTaskまわりがゴテゴテするけど、thisがまわりと統一できていい感じ。
本来DelayedTaskが便利なのは、キー入力が終わったら処理をするような場合など、連続するイベントが途切れたときに処理をするといった場合です。でも、コードがSencha APIとして統一できるというメリットもあるようです。
できあがったのがこれです。
https://dl.dropbox.com/u/16392316/timer/index.html
ChromeかSafariなど、WebKit系のブラウザで見てください。JavaFXのブラウザでも動きます。
ところで、Sencha Touch、このくらいのアプリなら普通にJavaScriptで書いてもいいし、画面をきれいにするにしても、jQuery Mobileのほうが楽な気がします。
Sencha Touchのメリットは、アプリケーションを記述する場所がちゃんと決められていてソース構造が統一できるということと、強力なデータAPIなので、ちょっと大きめのアプリでデータやりとりが多いものに向くのかなーと、改めて思いました。