Posted by & filed under 開発.


前回は Sencha.io のユーザーサービスを利用して、認証機能を作成しました。今回はアプリのメイン機能であるタスクデータの CRUD(作成、読み込み、更新、削除)機能を作成します。

– 一覧画面

jdi-2-1

– 作成画面

jdi-2-2

– 詳細画面

jdi-2-3

– 編集画面

jdi-2-4

今回のチュートリアルの完成形は、以下の URL から利用できます。

JDI at Tutorial #2:
http://apps.kawanoshinobu.com/jdi-2

JDI は HTML5 is Ready App Contest で 1 位を獲得した Sencha Touch アプリです。アプリの概要については、チュートリアル #0 を参照して下さい。

Sencha Touch Tutorial: HTML5 is Ready App Contest 1位アプリ「JDI」を作る #0:
http://dev.ariel-networks.com/wp/archives/3270

Model for CRUD

JDI では、データは Sencha.io のストレージに保存します。Sencha.io のデータサービスでは、データはまずブラウザの LocalStorage に保存され、オンライン時に Sencha.io のストレージと同期します。そのため、オフライン時でもデータの CRUD 操作が可能です。モバイルアプリは電波の通信状況が悪い場所で利用されることが多いので、この特徴は大変ありがたいですね。

jdi-2-5

JDI の CRUD 機能は MVC パターンに則って構成されています。まずはモデルを作成しましょう。

model/Task.js

ここでは「title」「duration」「due」「created」「updated」「completed」「deleted」の 7 つのフィールドを定義しています。そして「title」フィールドに対して、「presence(値必須)」のバリデーションを定義しています。

ここで興味深いのは、「due」「created」「updated」「completed」フィールドのデータ型に、独自に作成した型「datetime」を指定していることです。コメントを読むに、標準の date 型だと Sencha.io でうまく同期できないようで、日付を文字列に変換して扱っています。このクラスの他の記述も、その変換を行うことが目的です。将来的には改善されるはずですが、現状ではこのハックが必要のようです。。

続いて、ストアを作成します。ストアは、モデルの集合を扱うためのクラスです。名前には複数形をつけるのが慣習です。

store/Tasks.js

コンフィグオプションを以下のように定義します。

利用するモデルに先ほど作成した「App.model.Task」クラスを指定します(*1)。続いて Sencha.io のデータサービスを利用するためのプロキシを定義します。type に「syncstorage」を(*2)、id にアプリのストレージ内で一意になる値を設定します(*3)。owner にはデータの所有者を指定します。ここでは「user」を指定して下さい(*4)。access では作成するデータに対するアクセス権限を指定します。private は、作成したユーザーのみがアクセスできるデータです。他に public が指定でき、こちらは同じ認証グループ内のユーザーであれば誰でもアクセスできるデータになります。タスクは個人のデータなので、ここでは private を指定します(*5)。

filters オプションは、データを読み込む際、絞り込むデータの属性を指定します。削除されたタスクは除外したいので「deleted」フィールドが false のデータのみを対象にします(*6)。grouper オプションで、タスクデータをグルーピングするための関数 groupFn とグループをソートするための関数 sorterFn を定義しています。期限日毎にグルーピングして「late」「today」「tomorrow」「soon」「someday」順にソートしています。細かな実装は util/Date.js を参照下さい。グループ内のタスクデータは「due」「duration」「create」「title」順にソートするよう指定します(*8)。

このクラスでは他に sync メソッドをオーバーライドして、Sencha.io との同期が重なってエラーになる問題を解決するためのハックをしてます。こうしてみると、Sencha.io を利用するにあたり、いろいろと苦労されたことが伺えます。。Sencha.io はまだ β 版なので仕方ないですね ^^;

broadcast メソッドでは、他のデバイスに対してデータの同期を実行しています。このメソッドは Sencha.io との同期が成功した後に実行されます。

View for CRUD

それでは、目に見える部分(View)を作りましょう。これから作成するのは「作成」「一覧」「詳細」「編集」画面です。

作成画面

view/TaskForm.js

Ext.form.Panel クラスを継承した入力フォームです。このフォームでは「title」「due」「duration」フィールドの値が入力できます。また、ユーザーは所要時間(duration)を分単位で入力するのですが、プログラム内では秒単位で扱うため、その変換を行っています。本来は変換処理はフォームクラスが行うのではなく、フィールドとして指定できる「duration」クラスを独自に作って、そのクラス自身が行うべき(クラスの内部で隠蔽するべき)、ということで **[HACK]** というコメントが残されています。

view/TaskCreate.js

タスクの作成フォームを表示するパネルです。ここで興味深いのは、ボタンのタップイベントを一旦ビューが受け取っていて、ビューに関わる処理がこのビュー内で閉じていることです。具体的にはタスクの作成が完了した後のフォームの初期化やパネルの非表示はコントローラではなく、パネル自身が制御しています。コントローラに委譲したい処理に関しては、カスタムイベントを発火して通知しています。

一覧画面

view/TaskListitem.js

一覧は「ヘッダー(グルーピングしたデータの種類を示すラベル)」と「項目」の 2 種類の行で構成されます。TaskListitem.js では、これらの表示を制御するために 2 つのクラスを定義しています。

App.view.TaskListHeader クラスは Ext.Component を継承したクラスで、ヘッダーのデザインに関する調整を行います。このクラスは後述する App.view.TaskListItem クラスからのみ利用されます。

App.view.TaskListItem クラスは Ext.dataview.component.ListItem を継承したクラスで、コンポーネントを組み合わせてデータを表示します。dataMap オプションを使わず、自前で子コンポーネントを配置して、データをセットすることで細かな制御を行っています。

詳細画面・編集画面

view/TaskPanel.js

詳細画面、編集画面を内包するパネルです。ユーザーのボタン操作に応じて、画面を切り替えます。TaskCreate と同様、見た目に関する制御はコントローラではなく TaskPanel 自身が担うように設計されています。また、内包する各コンポーネントに容易にアクセスできるよう、プライベートな _refs 変数を宣言し、各コンポーネントを参照しています。

最終的に詳細パネルは、タブレットの場合はツーペインで常に表示され、スマートフォンの場合は必要に応じて開閉します。これらの制御に関わる処理もこのクラス内で記述されています。スマートフォン・タブレットの表示切替は以降のチュートリアルで改めて解説します。

view/TaskDetails.js

与えられたデータを詳細表示するクラスです。値があるフィールドに関してのみ、項目を表示する仕様です。このクラスでもコンポーネントの参照を持つ変数を定義し、各コンポーネントへのアクセスを容易にしています。

これらのクラスを Main パネルに配置して完了ですが、その前にもう一点。

widget/AutoBoxLayout.js

JDI では「autobox」という独自のレイアウトタイプを作成しています。これはデバイスの向きを変えた場合、reverse オプションが true であれば、縦持ちの場合は「horizontal」に、横持ちの場合は「vertical」に配置が変わるレイアウトです。次回のチュートリアルで紹介するセッション機能のために作られたレイアウトですが、メインパネルのレイアウトも「autobox」を指定しているため、今回ご紹介しました。

以上で View の作成は完了です。

Controller for CRUD

最後にコントローラクラスを作成します。

controller/Task.js

Task コントローラでは、作成、編集、削除、同期など、タスクデータを制御する処理が実装されています。

初期化

tasks ストアの更新イベント、削除イベントに対して、イベントハンドラを設定しています(*1)。また Sencha.io から通知を受け取った際にストアを同期をするよう usermessage イベントにイベントハンドラを設定しています(*2)。

ビューへの更新依頼

Task コントローラでは currentTask というプロパティを持ち、この値が変更されたタイミングで TaskPanel にレコードをセットし、ビューの更新を依頼します。

config で currentTask オプションを定義しています(*1)。クラスシステムの仕組みにより、自動で currentTask オプションに対する getter/setter(getCurrentTask、setCurrentTask)が定義され、値の変更時に updateCurrentTask メソッドが実行されます。updateCurrentTask メソッドでは TaskPanel に変更されたデータをセットします(*2)。一覧の項目を選択した時や、後述する項目のスワイプでデータを更新した際に currentTask プロパティの更新が行われます(*3)。

作成画面表示

ツールバーの作成ボタンのタップイベントを受け取って TaskCreate パネルを表示します。

作成画面は、アプリの初期起動時には生成せず、利用時に初めて画面を生成しています(*1)。アプリの初期表示を速くするための工夫ですね。

一覧のイベントハンドリング

一覧の操作に対して、イベントハンドラを定義してます。selectionchange イベント(選択行の変更)に対して、currentTask プロパティの更新を行うイベントハンドラを設定しています。また JDI では、一覧の項目をスワイプすることで、タスクデータを更新できます。itemswipe イベントの内容に応じて以下の制御を行います。

タスクが既に完了済み(completed に値が入っている)の場合、左にスワイプしたのであればタスクを未完了に戻す処理を(*1)、右にスワイプしたのであればタスクを削除する処理を実行します(*2)。未完了タスクの場合は、右にスワイプすることでタスクを完了する処理を行います(*3)。

タスクデータの追加・更新

ビュー(TaskCreate・TaskPanel)が発火するボタン操作のイベントを受け取って、タスクデータを更新します。

タスクデータの削除は物理削除ではなく、deleted フラグを更新するだけの論理削除です(*1)。

データの同期

タスクデータが更新された後、ストアの同期を行います。

同期に成功した場合、Sencha.io の通知サービスを使って、他のデバイスに対してデータの同期を依頼します(*1)。broadcast メソッドは App.store.Tasks クラスで定義しましたね。_onSIOuserMessage メソッドは受け取り側の処理です。他のデバイスでの変更通知を受け取って、自身のストアを同期更新します(*2)。

以上で Task コントローラの主な実装は完了です。その他、ビューに関わる処理が少し記述されています。詳しくは以降のチュートリアルで解説しますが、これは最終的には phone プロファイルで表示する場合のみ利用します。具体的には TaskPanel の開閉と TaskPanel 上でスワイプした際にパネルを閉じる処理です。

全てのコードを解説することはできませんでしたが、リンク先のファイルを参考に、これまで紹介したクラスを実装してみて下さい。

Apply makeup

今回解説した機能で必要になるスタイルが記述された scss ファイルは以下です。

resources/sass/stylesheets/dark
├── views
│   ├── _taskcreate.scss
│   ├── _taskdetails.scss
│   ├── _tasklist.scss
│   └── _taskpanel.scss
└── widgets
  ├── _list.scss
  └── _picker.scss

スタイルに関しては、最後にまとめて解説します。ここまでのアプリを動作させたい場合は、上記のリンクを参考にファイルを作成して下さい。

Conclusion

今回までの内容を反映したリポジトリを用意しました。都合上全てのコードを解説していませんので、説明が不足している箇所に関しては、このリポジトリのコードを参考にして頂ければと思います。

jdi-at-tutorial-2:
https://github.com/kawanoshinobu/jdi-at-tutorial-2

See Also:

jdi (Original):
https://github.com/simonbrunel/jdi

How to use Data Services:
http://docs.sencha.io/current/index.html#!/guide/concepts_store


関連文書:

Posted by & filed under いろいろ.


と言うことです。先日来たVに「いつまであんなもん、メンテナンスしてるんだ?暇人め」と言われたような気もしますが、気にしません。そう言えば、雑談ばかりでやつは何しに来たんだ? と言うことはいいとして、Pythonのwebsocket-clientの0.11.0(python2.7,python3.3)をリリースしました。この人は、もともとはWebsocketのプロトコルの勉強のために作ったので、メンテナンスするつもりはありませんでした。なので、メンテナンスした人にはプレゼントします。spdyも何かやろうかとドキュメントを少し読んだのですが、control frameあたりで飽きちゃいました。

[続きを読む…]


関連文書:

  • 関連文書は見つからんがな

Posted by & filed under 開発.


Special thanks to Simon Brunel, creator of JDI. He gave me permission to use JDI’s code to describe how to develop Sencha Touch apps. I sincerely appreciate his great works and fraternity!

それでは JDI の作成に取りかかりましょう。今回は、アプリへの認証機能を実装します。

– ログイン画面

jdi-1-1

– ログアウト画面

jdi-1-2

今回のチュートリアルの完成形は、以下の URL から利用できます。

JDI at Tutorial #1:
http://apps.kawanoshinobu.com/jdi-1

JDI は HTML5 is Ready App Contest で 1 位を獲得した Sencha Touch アプリです。アプリの概要については、チュートリアル #0 を参照して下さい。

Sencha Touch Tutorial: HTML5 is Ready App Contest 1位アプリ「JDI」を作る #0:
http://dev.ariel-networks.com/wp/archives/3270

On your mark!

プロジェクトの作成と Sencha.io の準備を行います。

プロジェクトの準備

プロジェクトのディレクトリを作成して、application というディレクトリ以下に Sencha Touch アプリの雛形を生成します。

JDI では、データの永続化とログイン認証、異なるデバイス間でのデータの同期に Sencha.io を利用しています。Sencha.io の API を利用するために application 以下に libraries/sencha-io ディレクトリを作成して、そこに Sencha.io SDK を配置します。

Sencha.io SDK:
http://download.sencha.io/sencha-io-0.7.13.zip

プロジェクトの準備を簡単に行うために、雛形プロジェクトを作りました。上記の手順を手作業で行う代わりに、以下のリポジトリを利用しても構いません。clone した後 Ant の initialize タスクを実行し、その後 Sass のコンパイルを行って下さい。

https://github.com/kawanoshinobu/sencha-io-app-template

Sencha.io

Sencha.io 側でアプリの準備を行います。まだアカウントがない場合は、以下の記事を参考に作成して下さい。

Practical Sencha Touch #3: Sencha の BaaS「Sencha.io」を使う:
http://dev.ariel-networks.com/wp/archives/3058

Sencha Cmd を使って Sencha.io にアプリを作成します。この際に生成される AppId は開発時に必要になるので書き留めておいて下さい。その後、アプリで利用する認証グループを作成し、アプリと関連づけます。

$ sencha io create-app jdi {$ユーザー名} {$パスワード}

以上で下準備は完了です。実際にコードを書き始める前に、開発時の注意を 2 点。

Touch 2.2 で生成したプロジェクトでは、開発時に利用するフレームワークのコードが sencha-touch.js になっています。ただ、このままだとコードが圧縮されていてデバッグしづらいのと、エラーや警告を出してくれないので sencha-touch-all-debug.js を利用するように変更した方がよさそうです。

また開発時に利用するファイルの動的ローディングでは、現在のタイムスタンプをパラメータに指定して読み込むことで、ブラウザのキャッシュを回避しています。ただ、この仕組みだとデベロッパーツールでブレークポイントを張れません。コードをデバッグする時は Ext.Loader のコンフィグで disableCaching オプションに false を指定するとよいでしょう。

Get set, start coding!

お待たせしました、それでは認証機能の実装を始めましょう。application ディレクトリに移動し Main コントローラを作成します。

続いて application/app.js で Sencha.io のアプリとの関連づけを行います。

Ext.Loader に Sencha.io クラスの読み込みの設定を行います(*1, *2)。また io コンフィグの appId オプションに Sencha.io アプリの AppId を指定します(*3)。そして contollers オプションで Ext.io.Controller クラスを読み込むように指定します(*4)。この際、Main コントローラの後に Ext.io.Controller を読み込むよう指定する必要があるので注意して下さい。

実はこれだけで、認証機能が実装できてしまいます。未認証のユーザーの場合、ログイン画面が表示されます。認証後はログアウトボタンが表示されます。アカウントがないユーザーのための新規登録画面も用意されます。

jdi-1-3

このように Sencha.io と関連づけることで、自動で認証機能が備わります。ただ、今回は独自のログイン画面・ログアウト画面を作りたいので、io コンフィグに以下の設定を追加します。

ログインのタイミングを自由に実装できるよう manualLogin オプションに true を指定します(*1)。これで自動で認証画面が表示されなくなりました。その場合でも、authOnStartup オプションに true を指定して、起動時に認証は行うようにしておきます(*2)。

認証機能の構成

JDI では、認証機能を実現するために以下のクラスが構成されています。

View

view/AuthPanel.js

メールアドレスとパスワードを入力するログインフォームです。ログインボタンとアカウント登録ボタンを用意して、状況に応じて表示を切り替えています。また、ボタンのタップイベントを一旦ビューでハンドリングして、その後カスタムイベントを発火してコントローラ側に処理を委譲しています。

view/SplashScreen.js

アプリのロゴ、認証後に表示するユーザー情報パネル、認証フォームを保持するコンテナです。また、状況に応じてユーザー情報パネルを表示するか、認証フォームを表示するかを切り替えます。また JDI ではログインしたユーザーの顔写真を表示するために Gravatar API を利用しています。API へのリクエストが完了した後、userloaded イベントを発火します。

view/UserPanel.js

ユーザー情報(画像、アカウント名、メールアドレス)とログアウトボタンを表示するパネルです。

view/Main.js

アプリのメイン画面です。今回はツールバーだけを配置しています。

view/ToolBar.js

JDI 用にカスタマイズしたツールバーです。今回はユーザーパネルを表示するためのボタンだけを配置しています。

Widget

JDI では view ディレクトリと controller ディレクトリに並列して widget ディレクトリを作成しています。このディレクトリにはビューよりも細かい単位の再利用可能なコンポーネントを配置しています。

widget/ToolButton.js

状態を持つボタンです。チェックしている時とそうでない時で見た目を切り替えます。

Controller

controller/Main.js

Sencha.io の初期化、ユーザーのログイン・新規作成・ログアウト、SplashScreen の表示などアプリ全体に関わる処理を行うコントローラです。

controller/User.js

Gravatar API を使った画像データの取得やユーザー情報の表示を制御するコントローラです。

都合上細かい説明は割愛しますが、リポジトリを参考にコードを写経してみて下さい。これらのクラスを実装すると、以下の表示になります。

– ログイン画面

jdi-1-6

– ログアウト画面

jdi-1-5

認証の流れとしては、まず Ext.Viewport に SplashScreen ビューを追加し、未認証の場合に SplashScreen を表示、そうでない場合は SplashScreen を破棄することで、ログイン画面を制御しています。認証には Sencha.io の Ext.io.User.authenticate メソッドを利用しています。認証後はメールアドレスを元に Gravatar API を使ってユーザー画像を取得し表示します。ログアウトボタンのタップイベントをトリガーに Sencha.io の API をコールしてログアウトします。

Apply makeup

機能の実装が完了したら、見た目を調整しましょう。JDI では、dark.scss というファイルを resources/sass ディレクトリに作成しています。アプリケーションで dark.scss をコンパイルして出力される dark.css ファイルを利用するよう app.json を以下のように変更します。

JDI で特徴的な部分として Android の Roboto フォントが使われている点が挙げられます。フォントファイルを resources/fonts ディレクトリに配置して、Sass のコンパイル時に参照できるよう config.rb を変更します。これに伴い、resources/sass/stylesheets/pictos ディレクトリも application/resources ディレクトリに移動します。

今回の認証機能に必要なスタイルの記述は、以下のリポジトリを参考にして下さい。詳細の解説は割愛させて頂きます。

https://github.com/kawanoshinobu/jdi-at-tutorial-1/tree/master/application/resources/sass/stylesheets/dark

また前回のチュートリアルでもお話しましたが、Touch 2.2 では $font-family 変数が動かなくなっています。フレームワークの _Class.scss ファイルに以下の変更を適用して下さい。

Conclusion

駆け足でしたが JDI の認証機能について解説しました。今回取り上げた内容を反映したリポジトリを以下に用意しました。説明が不足している箇所に関しては、このリポジトリのコードを参考にして頂ければと思います。

jdi-at-tutorial-1:
https://github.com/kawanoshinobu/jdi-at-tutorial-1

See Also

jdi (Original):
https://github.com/simonbrunel/jdi

How to use User Services:
http://docs.sencha.io/current/index.html#!/guide/concepts_user


関連文書:

Posted by & filed under いろいろ.


先日リリースされたFirefox21でE4Xが完全削除されました。
https://developer.mozilla.org/ja/docs/Mozilla/Firefox/Releases/21#JavaScript

アリエルではAquaDesignerという製品でがっつりE4Xを使ってました。私が初めてAquaDesignerチームに入った時はまだ私がJavaScript自体にも慣れてなかったこともあり、この奇妙な文法には苦戦させられました。またXMLの作成処理が遅いので試しに

$A(arguments).each(function(dao) {
  // dataとsynchronizeDataの戻り値はXMLオブジェクト
  data.property += dao.synchronizeData();
});

となってるところを

$A(arguments).each(function(dao) {
  data.appendChild(dao.synchronizeData());
});

にしたら15倍速くなったってこともありました(E4Xのプロパティアクセスと比較演算子)。

Firefox17でのE4Xデフォルト無効をきっかけに、AquaDesignerはE4XでやってたXML操作を全部DOMParserやquerySelectorなどに置き換わりました(私が担当したわけではないのですが)。副作用としてこれまでFirefoxでしか動かなかったのがIE10やChromeなどでもそれなりに動くようになりました。もし読者のなかにAquaDesignerのユーザーが居られたらバージョンアップの検討をおすすめします。

ところでnashornのlexerにあるXML_LITERALSってこれはいったい…
http://hg.openjdk.java.net/nashorn/jdk8/nashorn/file/40c107d1ae6f/src/jdk/nashorn/internal/parser/Lexer.java


関連文書:

  • 関連文書は見つからんがな

Posted by & filed under 製品.


Sencha Touch を使った Web アプリ開発では HTML を直接記述せず、組み立てたコンポーネントが自動的に HTML を出力します。コンポーネントがどのような HTML を出力するかはブラックボックスのようですが、実は elementConfig という定義情報を元にしています。今回は、カスタムコンポーネントを作成する際に便利な elementConfig の拡張方法について紹介します。

Problem:

コンポーネントが出力する HTML 要素を自由に指定したい。

Solution:

template プロパティで HTML の出力情報を定義します。

このコンポーネントは以下のように表示されます。

comp-template

出力される HTML 要素は以下です。

Discussion:

一番外側はコンポーネントとして最低限必要な div 要素です。その中身は template で指定した内容を元に HTML 要素が出力されています。

コンポーネントの HTML 要素は AbstractComponent.js の initElement メソッド内で生成されます。ここで getElementConfig で取得した情報を元に Ext.Element.create メソッドを使って要素を生成しているのですが、その定義情報を拡張する手段として用意されているのが template プロパティです。

既に template プロパティが定義されているコンポーネントを継承している場合、template プロパティを設定すると継承元の定義を上書きしてしまうので要注意です。その場合は getTemplate メソッドをオーバーライドする方法で指定した方がよいでしょう。

ただ、 getElementConfig メソッドを独自に上書きしているコンポーネントがあって、templete プロパティが無視されてしまうことがあります。container コンポーネントや toolbar コンポーネントなどが、それに該当します。。その場合は、仕方ないので、getElementConfig メソッドを直接オーバーライドして追加で定義を足す必要があります。

タグの属性は、どのようなものでも指定することができます。詳しくは Ext.dom.Element クラスの create メソッドを参照して下さい。

また reference という便利なプロパティがあります。reference プロパティを使えば、コンポーネントから要素に簡単にアクセスできます。

コンポーネントが出力する HTML を制御できると、Sencha Touch が身近に感じてきますね。以上、カスタムコンポーネントを作る時などに便利な elementConfig の拡張方法でした。


関連文書:

Posted by & filed under 開発.


開発部 川野です。ゴールデンウィークでまとまった時間が取れたので、長らく放置していた Ext.ux.AccordionList のメンテナンスを行いました。Ext.ux.AccordionList は自作した Sencha Touch のカスタムコンポーネントで、項目を折り畳めるリストです。やりたいことが一通り完了したので、この機会にバージョン「1.0」と呼ぶことにしました :)

変更点は以下です。

– Sencha Touch 2.2 対応
– コードのリファクタリング
– コンフィグオプションを追加(headerItemCls, contentItemCls, useSelectedHighlights, etc)
– サンプルを追加(複雑な入れ子ができることが分かるサンプル)
– Jasmine と Phantomjs ベースの単体テスト
– API ドキュメントを整備

accordion1 accordion2

ドキュメントはお馴染みの JSDuck を使って、憧れのライブプレビューを組み込みました。実は、ライブプレビューのデバイス画像は JSDuck の標準機能ではなく Sencha Touch 向けのハックのようです。デバイス画像を表示するには、ドキュメントビルド時に –touch-examples-ui という隠しオプションを true にする必要があります。

accordiondoc

テストはブラウザだけでなく、コンソールでも実行できます。

accordiontest

ずっと気がかりだったタスクが終わって、すっきりしました ^^ ありがたいとことに、海外では使ってくれている人がたくさんいるようなので、今後もメンテナンスを続けていきたいと思います。

See Also:

Repository:
https://github.com/kawanoshinobu/Ext.ux.AccordionList

Demo:
http://docs.kawanoshinobu.com/accordionlist

API Document:
http://docs.kawanoshinobu.com/touch/#!/api/Ext.ux.AccordionList

Sencha Market:
https://market.sencha.com/extensions/ext-ux-accordionlist


関連文書:

Posted by & filed under 開発.


先週の火曜日、Sencha Touch のバージョン 2.2 が正式リリースされました。2.2 では、これまでの WebKit 前提で記述されていたスタイルシートが改修され、Windows Phone 8 上でもアプリが動作するようになりました。今後、さらに対応プラットフォームが広がるものと期待しています :)

2.2 リリースを機に Sencha Touch を本格的に始める方もいるはず!ということで、今回から数回に分けて、実践的な Sencha Touch アプリを開発するチュートリアルを連載します。

Sencha Touch をほとんど触ったことがない方は、まずは以下のチュートリアルをおすすめします。2.2 になってテーマシステムが変わりましたが、それ以外の内容は 2.2 でも問題なく通用します。

Sencha Touch 2.1 のチュートリアルを書きました!:
http://dev.ariel-networks.com/wp/archives/2791

JDI

先日、Sencha 社主催の Sencha Touch アプリコンテスト「HTML5 is Ready App Contest」が行われました。今回のチュートリアルでは、そのコンテストで 1位を獲得したアプリ「JDI」を作成します。JDI はいわゆる ToDo アプリです。タスクを管理する機能の他に、隙間時間を使ったタスク消化を支援するユニークな機能が備わっています。また、バックエンドに Sencha 社が提供する BaaS「Sencha.io」を使っている点も興味深いところです。

JDI はソースコードが公開されているのですが、Sencha Touch 2.1 ベースで実装されています。でも、これから始めるなら 2.2 を使いたいですよね。ということで、私の方で 2.2 に対応する改修を行いました。

jdi:
https://github.com/kawanoshinobu/jdi

2.2 では、テーマシステムの $font-family 変数が使えないバグがあるので、フレームワークのコードを一部変更する必要があります。。フォーラムにバグ報告して修正してもらえたので、次のバージョンでは問題ないと思いますが、Touch 2.2.0 では、_Class.scss ファイルを以下のように書き換えて下さい。

上記のリポジトリを clone すれば、ローカルで 2.2 対応の JDI を動作させることができます。また、以下の URL で 2.2 対応の JDI を実際に試すことができます。

JDI with Touch 2.2.0:
http://kawanoshinobu.github.io/jdi

Just Do it!

実際の開発は次回から行うことにして、今回は、これから作成するアプリの機能について紹介します。

ユーザー登録

メールアドレスとパスワードを入力して、新規にユーザーを作成する機能です。データは Sencha.io のストレージに保存します。メールアドレスが Gravatar に登録されている場合、そのアバターをアプリで利用します。

jdi-1

ログイン認証

メールアドレスとパスワードを利用して、ログインの認証を行う機能です。認証は Sencha.io が提供する API を利用します。

jdi-3

タスク作成

作成フォームに「タスク名」「期限日」「所要時間」を入力してタスクを新規作成する機能です。タスクのデータも Sencha.io のストレージに保存します。

jdi-4 jdi-5

タスク一覧

タスクを期限日毎に「Late」「Today」「Soon」「Someday」の 4つに分類して一覧表示する機能です。完了したタスクはグレイアウトして表示します。削除されたタスクは表示しません。一覧の項目を、右にスワイプしてタスクを完了する、左にスワイプして未完了にする、完了したタスクを右にスワイプして削除する、といった操作を行えます。

jdi-6

タスク詳細

タスクの詳細を表示する機能です。一覧の項目を選択すると、右側からパネルが表示されます。×ボタン、もしくは右にスワイプすることで、パネルを閉じることができます。また、パネルのツールバーからタスクの完了、編集画面の表示、タスクの削除ができます。

jdi-7

タスク編集

タスクの「タスク名」「期限日」「所要時間」を変更する機能です。

jdi-8

JDI セッション

隙間時間を利用して、タスクの消化を支援する機能です。使える時間を指定してスタートボタンを押すと、その時間内に収まる所要時間のタスクが一覧表示されます。一覧では、タスクは「Active(未完了タスク)」「Done(完了タスク)」「Postponed(後で行うことにしたタスク)」「Out of time(残り時間内では完了できない所要時間のタスク)」の 4つに分類されて表示されます。一覧の項目を、左にスワイプしてタスクを延期する、右にスワイプしてタスクを完了する、左にスワイプして未完了にする、完了したタスクを右にスワイプして削除する、といった操作を行えます。

jdi-9

ヘルプ

JDI には、機能毎にヘルプが備わっています。画面各所にある「?」アイコンが該当のヘルプページにリンクされています。また、アプリの情報やサンプルデータを自動生成する機能があります。

jdi-10

サインアウト

アプリからサインアウトする機能です。

jdi-11

スマートフォン・タブレットの表示最適化

アクセスしたデバイスに応じて画面のレイアウトを切り替えます。スマートフォン以外のデバイスからアクセスした場合は、ツーペイン表示になります。

jdi-12

これから開発するアプリのイメージが掴めたでしょうか?JDI、かっこいいですよね。私はとても気に入っています。それでは次回から、開発プロジェクトをスタートしましょう!

See Also

jdi (Original):
https://github.com/simonbrunel/jdi


関連文書:

Posted by & filed under 勉強会.


開発部 川野です。先日行われた 第4回 XPF(クロスプラットフォーム)開発技術勉強会で Sencha Touch をご紹介させて頂きました。

以下、発表資料です。

前半は Sencha Touch の概要をお話し、後半はライブコーディングを行いました。クロスプラットフォームのモバイルアプリを実装する手段として HTML5(Web)アプリは理想的だと思います。その一方で、満足いく性能で動作させることは難しい、という側面もあり。。そこで頼りになるのが Sencha Touch です。解説書も発売されたことですし、始めるなら今ですよ!(本、買って下さい)

参考リンク

Sencha Fastbook:
http://fb.html5isready.com

Sencha Fastbook Demo (Vimeo):
http://vimeo.com/55486684

JDI:
http://jdi.abysscorp.org

JDI Source Code (GitHub):
https://github.com/simonbrunel/jdi

Weathy:
http://www.loopthy.com

Snapmate:
http://snapsmate.com

Sencha Touch App Gallery:
http://www.sencha.com/apps

Sencha Touch API Documentation:
http://docs.sencha.com/touch/2-1


関連文書:

Posted by & filed under いろいろ, 開発.


ラスボスが気まぐれで始めたコロコロ教ですが、まだ続いているみたいですよ。

そんな中でコロコロ教の存在を脅かす新たな勢力が現れました。
それは、グルグル教です。

IMAG0466
グルグル教とはパワーボールを使ってトレーニングを行う新興宗教で、パワーボールを回せるという特殊能力を持った選ばれし者によって構成されています。

IMAG0470
指先から肩までの広範囲の筋肉をトレーニングできるので、壁バカに大受けです。
がしかし、回せない残念な人もいます。

IMAG0467
回そうとしても回せない残念な人

IMAG0469
本場パワーボール(左)とそのパチもの(右)

powerball
頑張って両手で回している図

皆様も是非パワーボールで壁バカになりましょう。


関連文書:

  • 関連文書は見つからんがな

Posted by & filed under 開発.


Sencha Touch のクラスシステムには、プロパティの getter / setter を自動生成し、変更前に値を検証するメソッド(applier)、値の変更後に実行するメソッド(updater)を呼び出す機能が備わっています。今回は、この updater のハマりポイントに関するトピックです。

Problem:

コンポーネントの hidden プロパティや disabled プロパティの updater(updateHidden、updateDisabled)を定義したが、値を変更してもメソッドが呼び出されない。

Solution:

プロパティの updater として実行するために、doSet{$プロパティ名} メソッドを定義します。

*1 ”EventedConfigTest” という名前のクラスを定義
*2 ”Ext.Component” クラスを継承
*3 hidden プロパティに対する applier を定義
*4 hidden プロパティに対する updater を定義
*5 hidden プロパティの updater として実行するために doSetHidden メソッドを定義
*6 ”EventedConfigTest” クラスのインスタンスを生成
*7 インスタンスの hidden プロパティの値を確認。このタイミングでは値に null が設定されている
*8 インスタンスの hidden プロパティに true を設定する
*9 applier が実行される
*10 updater は実行されない。定義した doSetHidden は実行される
*11 インスタンスの hidden プロパティの値を確認。値に true が設定されている
*12 もう一度、インスタンスの hidden プロパティに true を設定する
*13 applier が実行される。値の変更がないので、doSetHidden は実行されない

updater-problem

Discussion:

実は、コンポーネントのプロパティには、通常のプロパティの他に Evented なプロパティがあります。Ext.Component のソースコードを見ると、config オプションの他に eventedConfig オプションを定義していることが分かります。eventedConfig オプションは、初期化時の change アクションの実行を抑制するために利用されています。初期化時のパフォーマンス改善が目的のようです。

この eventedConfig オプションで定義したプロパティは config オプションで定義したプロパティと同様、getter / setter が自動生成されるのですが、挙動が微妙に異なります。そして最大の違いは、なんと updater が実行されないことです。。内部ではプロパティの値を変更した後、updater と似た用途で doSet{$プロパティ名} メソッドを実行しています。そのため、doSet{$プロパティ名} メソッドを定義することで updater の代替にできる、という解決策でした。

この解決策を採る際、doSet{$プロパティ名} メソッドで親クラスの同名メソッドを実行することを忘れないようにして下さい(具体的には、this.callParent(arguments) を忘れずに記述して下さい)。そうしないと本来実行されるべき処理が実行されなくなってしまいます。

正直なところ、doSet{$プロパティ名} メソッドの継承は、公式には推奨されていません。doSet{$プロパティ名} メソッドを継承するより、set{$プロパティ名} メソッドを継承して、処理の後、自前で updater 用に定義したメソッドを呼ぶ方が、バージョンアップで仕様が変わった際に安全かもしれません。微妙なノウハウですが、Evented なプロパティで updater が実行されないケースは結構ハマりがちだと思うので、今回ご紹介させて頂きました。

※個人的には、Evented なプロパティの場合でも、doSet{$プロパティ名} メソッドではなく、update{$プロパティ名} メソッドを実行するように仕様変更されることを願います。。

See Also:

How to Use Classes in Sencha Touch:
http://docs.sencha.com/touch/2-1/#!/guide/class_system

Sencha Touch ソースコード:
Evented.js
AbstractComponent.js
Component.js
core/class/Class.js


関連文書: