Sencha Touch 2 + PhoneGap(Cordova)での開発メモ

死ぬほどハマったしいまでもわからないところあるけどすべてを投げ出してメモする。箇条書きのメモベース。

model, store, Ext.Ajax 関連

model の setData, getData は model 内の data と同じ

つまり、 Ext.data.Model で定義した field があって、それらの data と同じ。ゲッターとセッター。ただ、save するには setData じゃなくて record を更新しないといけない。そこがいまだによくわからない。

model.save() するとき proxy をとおしてやりとりする

そのまま。type: ajax してるなら、Ext.Ajax 相当のことをしてくれる。なので、Ext.Ajax.addListener("beforerequest") とかでフックできる。フックできるのなら、好きにロガー仕込んだりもできる。

save 時の PUT DELETE

公式ドキュメント嫁だけど、たしか methods か actions で渡すことができる。デフォルトだと params なしだと GET ありだと POST になった気がする。具体的には Ext.data.Oparation を読んだらいい気がする。

idProperty がデフォルトでついているけど、そうするとクエリストリングに id= とかついてしまう問題

消さないと困る場合は setIdProperty("none") とかで消せばいいけど、モデルを扱うと内部処理的には使うっぽくてハマる。なので差し替える必要がある。つまり、load のオーバーライド(か、callback時)にあらかじめ model.getIdProperty() しておいて保存、処理内部でmodel.setIdProperty() でもとに戻す

override について

差し替えたい場合は touch/src/ 以下などにソースがあるので読む。model の inheritableStatics 内で(staticsではない) save などを差し替える。で、callSuper() して呼び出す。ちなみに callSuper 自体は Ext.Base にある。proxy 内で actionMethod を update(PUT), destory(DELETE) と差し替える必要があった気がするけど、僕にはよくわかってない

model record のトランザクション

model.beginEdit(), model.calcelEdit(), model.Endedit() というようにモデルを更新するときはトランザクションのようなものをもたないといけないかもしれない。 model.validation() したときに model.cancelEdit() する、みたいな。

ユーザー model をlocalStorageに保存するとき

JSON.stringify() と JSON.perse()で

model.load は static method

なので a = Ext.create("myapp.model.A") してクラスを生成したら、a.load() としてつかえる。実際はその load を API 仕様にのっとって差し替えたりする必要があるけど、そもそも load は static method だ。クラスを作ってからインスタンスを取り出すということがわかってなくてだめだった。

form.updateRecord(model) など record を扱う

いまだによくわかってないけど、data じゃなくて record を扱う必要がある。record には field があるので、それをもとに value を取り出したりできる。

View

Panel に tap イベントはない。公式ドキュメント嫁

画像をいい感じにはめたいとき、xtype: image ではなく xtype: panel にして html の中で img 要素作って width height を指定したほうがうまくいきやすいんだけど、そうすると tap イベントがとれない。仕方ないので image をつかって、どうにかやりくりする。

画面遷移を管理したいとき自前でつくったほうが良いのでは

Ext.Viewport.removeAll() と Ext.Viewport.add(Ext.create("someView")) をつかえばたしかに破壊的に切り替えられるけど、そのたびに初期化が発生する。それはこまる。単に画面遷移を管理したいだけなら、独自にクラスをつくったほうがよさげ。今回は singleton: true で独自に配列に View をいれてしまって push, pop するようなものをつくってくれて助かった。このとき animeteActiveItem をつかってたし、やりやすかった。Ext.navigation.View はたしかにある程度使えるけど、そうでないときは自前。

静的生成と動的生成

基本的に View は静的に myapp.view.SomeView で定義してしまいそのなかにいれてしまうのだけど、なんらかのかたちで画面遷移したときに初期化処理をしたい場合とかは動的に追加するしかない。その場合、画面遷移する前に view_instance.add(View) や view_instance.insert(index, View) して組み立ててしまえばよい。

要素をとってくる

xtype か id で指定。xclass は controller 内ではつかえないっぽい。controller 内で refs と control で指定するけど、そのとき refs で logoHoge とかあったら this.getLogoHoge() としてその要素をとってこれる。

要素をとってくる - View をまたぐとき

Ext.select(componentQuery) をつかえばよい。具体的には id を指定してやった。

色指定(SCSS)

基本的には app.scss で

だいたいよしなにやってくれる。色変更は愚直なCSSはさいあくできるけど、component なら 公式の CSS Variables をみればできる。逆に言うと、公式からはずれたカスタムなことをしようとするとすごくたいへんなことになるから、それはたぶんできないと言ったほうがよい。

mixin は自作できる

独自アイコンとかは mixin で見よう見まねでいれたほうが楽っぽい。base64 エンコードしていれるとか方法あった気がするけど、なんかうまく行かなった気がする。

その他

アプリラベルを完全に消す(Android)

アプリ管理の画面で @string/app_name を表示させたい。この場合 Manifest.xml にある android:theme="@android:style/Theme.Black.NoTitleBar" を消すこと。cordova-incubator-android したとき自動生成されていた。

window.self があるので this の bind には me をつかおう

Sencha 内部でも何回も me で統一されている。JS としては self とか _this とかにいれることがあるけど、慣習的に me を使ったほうが無難

Ext.define(name, params, createdFunc)について

createdFunc がクラス定義作成時のコールバック関数なので、既存クラスを与えてやればオーバーライドできる(ここはまだあんまりよくわかってない)。また、別に extends しないただのなんもないクラスをつくって、そこに statics なりなんなりで定義して好きに使うこともできる。また、Ext.define('myapp.view.Hoge',{})みたいにつくるのはいいけど、Ext.define("myapp.view.user.Hoge")みたいに階層を掘ることもできる。要は最終的なクラスネームがJavaみたいに大文字始まりじゃなきゃいけないだけで、あとは好きに定義していいということ。staticsがついている階層なら static method(class method)で、そうでなければ instance method になるというだけの話。

Ext.application()について

app.js で読み込み時に最初に発火するところだから、アプリ起動時のなんらかの判定やなにかをしたい場合ここに定義してやればいい。

PhoneGap(Cordova)の話

基本的な話

それ自体はそんなに複雑ではなさそう(たぶん)だけど、実際いろいろバグがある。具体的にはカメラでEXIFが消える問題がある[#CB-1285] Include EXIF metadata in image upload - ASF JIRA。cordova自体どんどんバージョンアップしているけど、ちょっと挙動不審なよくわからないバグがひそんでる可能性はままあるので、案件で使うなら要件を詳細に先に聞いておかないと危険。逆に、ほんとうに単純なアプリならきっとだいじょうぶ。ネイティブを簡単にラップしてくれるなんて、そんなに簡単な話はなかった。

プラグインの話

画面要素は上記 Sencha Touch 2 でつくるとして、ネイティブデバイスへのラッパーとしてcordova のプラグインをつかうことはままあるけど、結局そのプラグインの内容が古かったり微妙に要件のとおりにとれなかったりするので、Objective-CJava の開発者はいたほうがいい。「JSだけ知ってればObj-CもJavaも知らなくていいですよ」とはいうが、いろいろハマることがあるのでそう銀の弾丸とはいかない。

個人的なまとめ

Sencha Touch 2はよくできているし*1、たしかにAndroidのなんか変な対応とかしなくてすんだ。それはよかったかもしれない。でもSencha Touch のクラスシステムは正直かなり手こずった。苦しかった。画面遷移とかも単純なサンプルアプリなら簡単だけど、ちょっと込み入った要件のアプリになるととたんにけっこう手こずる。できなくはない(というよりはやってもらった……)けど、だいぶくるしい。

Cordovaもまちまちな挙動になってしまう。「OSSなんだから自分で直せよ」と言われたらそれまでだけど、それをしたくないからCordovaつかってるのに……。

ところで

HTML5モバイルアプリケーションフレームワーク Sencha Touchパーフェクトガイド

HTML5モバイルアプリケーションフレームワーク Sencha Touchパーフェクトガイド


という本が出るらしいんですけど個人的には気になりますね……どういう内容なんでしょうね……。

*1:Sencha Touch 2 はよくできているが、うまく扱えない自分がだめすぎた