現在、作業が比較的落ち着いてるのと、先々考えても、Alloyはひとまず抑えておいたほうがよいかと思って、やや食わず嫌い気味だったAlloyを最近本格的にいじりはじめました。
過去何度かトライはしていたのですが、自分が欲しいサンプルアプリ(まずは画面遷移系のもの)の情報が見つからなかったことも有り、本格的な利用は躊躇してたこともあり、似たような人がいるかもしれないと思い、ひとまず画面遷移系のアプリについて以下に簡単にまとめておこうと思います
プロジェクト作成までの流れ
自分の実行環境
Titanium の新規プロジェクト作成する
CLIベースで最近作業してるので、ひとまずその流れを以下に示します。
※気が向いたら、Titanium Studioでの流れもキャプチャ付きでまとめておきたい
ホームディレクトリ配下に、titaniumというディレクトリがある前提での説明になってますので、適宜読み替えていただければと思います。
ti create --name=alloysample1 --id=info.h5y1m141.alloysample1--platform=ios
上記実行すると、オプション設定間違ってるからか、ターゲットのOSを聞かれるので、その後に、任意のOS(ひとまずiOS)と入力する。しばらくすると
Project 'alloysample1' created successfully in 90ms
という感じでプロジェクト作成完了します
Alloyを利用するための手順
Titanium の新規プロジェクト作成完了したら、今度はAlloyが利用できるようにします。
~/titanium % cd alloysample1 ~/titanium/alloysample1 % alloy new .__ .__ _____ | | | | ____ ___.__. \__ \ | | | | / _ < | | / __ \| |_| |_( <_> )___ | (____ /____/____/\____// ____| \/ \/ Alloy 1.3.1 by Appcelerator. The MVC app framework for Titanium. [INFO] Deployed ti.alloy plugin to plugins/ti.alloy/plugin.py [INFO] Deployed ti.alloy hook to plugins/ti.alloy/hooks/alloy.js [INFO] Installed "ti.alloy" plugin to tiapp.xml [INFO] Generated new project at: app
Alloyが利用できるようになったかと思いますが、念のためこの段階でbuildしてみます
ti build --platform ios
build完了すると、以下の様な画面が表示されるかと思います。
Alloy導入後のプロジェクトのディレクトリ構造は以下のようになります。
├── LICENSE ├── README ├── Resources │ ├── alloy │ ├── app.js │ └── iphone ├── app │ ├── README │ ├── alloy.js │ ├── assets │ ├── config.json │ ├── controllers │ ├── models │ ├── styles │ └── views ├── build │ ├── alloy │ ├── iphone │ └── map ├── plugins │ └── ti.alloy └── tiapp.xml
JavaScriptではなくCoffeeScriptで書きたいので、設定ファイルを編集する
Titanium×Alloy×CoffeeScript×Jadeでいいんじゃーねの情報を参考に、~/titanium/alloysample1/app/alloy.jmk を以下内容で作成します
task("pre:compile", function(event,logger) { var wrench = require("wrench"), fs = require("fs"), jade = require("jade"), view_root = event.dir.views, path = require("path"), coffee = require("coffee-script"); event.alloyConfig.xml = []; event.alloyConfig.coffee = []; wrench.readdirSyncRecursive(view_root).forEach(function(view) { if (view.match(/.jade$/)) { event.alloyConfig.xml.push(view.replace(/\.jade$/, ".xml")); fs.writeFileSync( path.join(view_root,view.replace(/\.jade$/, ".xml")), jade.compile(fs.readFileSync(path.join(view_root,view)).toString())(event)); } }); wrench.readdirSyncRecursive(event.dir.home).forEach(function(target){ if (target.match(/\.coffee$/)) { event.alloyConfig.coffee.push(target.replace(/\.coffee$/, ".js")); fs.writeFileSync( path.join(event.dir.home,target.replace(/\.coffee$/, ".js")), coffee.compile(fs.readFileSync(path.join(event.dir.home + "/" + target)).toString(), { bare: true })); } }); }); task("post:compile",function(event,logger){ var fs = require("fs"), view_root = event.dir.views, path = require("path"); event.alloyConfig.xml.forEach(function(view){ if (!view.match(/index.xml/g)) { fs.unlinkSync(path.join(view_root, view)); } }); event.alloyConfig.coffee.forEach(function(target){ fs.unlinkSync(event.dir.home + "/" + target); }); });
app/controllers/index.coffee
$.index.open() $.label.addEventListener 'click', (e) -> alert e.source.text
app/views/index.xml
<Alloy> <Window class="container"> <Label id="label">Hello, World</Label> </Window> </Alloy>
XMLでもいいのですが、上記でalloy.jmkにて、Jade利用できるようにしていたので、index.xmlではなく、index.jadeを以下のように準備しました
app/views/index.jade
Alloy Window.container Label#label Hello, World!!!!!!!
これをベースにして、画面遷移の方法を考えます
画面遷移系のサンプルアプリ
理解してしまうと簡単なのですが、そこに至るまでに意外と時間がかかったのも事実なのでここは少しじっくり解説していこうと思います。
作成するファイル&それぞれの対応関係
まず、現在作成中のプロジェクトのappディレクトリのcontrollers、styles、viewsにそれぞれ以下のようにファイルを作成します
- controllers
- index.coffee
- newWindow.coffee
- styles
- index.tss
- newWindow.tss
- views
起動時の画面&画面遷移後の画面イメージと、それぞれ対応するファイル群の対応関係を絵にしてみました
キモとなるコードの解説
上記の対応関係の紫色の枠&線でつなげてる部分が画面遷移する上でキモとなる処理になるかと思います。
具体的には
- 画面遷移先の処理と対応関係にある呼び出し先のコントローラーを 起動時に実行されるindex.coffeeに記述する
- 呼び出される側のコントローラーのファイルの newWindow.coffee
- 処理を渡した後に呼びだされるメソッドを実装する。
- 遷移後のWindowは、Window#newWindow.container という形でマークアップしており、id名であるnewWindowを指定してopen()にてWindowを開く
という感じです。
実際のコード
起動時の画面
index.coffee
$.mainWindow.open() $.label.addEventListener 'click', (e) -> newWindow = Alloy.createController('newWindow') return newWindow.move()
index.jade
Alloy Window#mainWindow.container Label#label Hello, World!!!!!!!
index.tss
".container": { backgroundColor:"#fff" }, "#label": { width: Ti.UI.SIZE, height: 40, color: "#000", top:50, left:10 }
遷移後の画面
newWindow.coffee
exports.move = () -> alert "Moved!" return $.newWindow.open()
newWindow.jade
Alloy Window#newWindow.container Label#label This is a new Window
newWindow.tss
".container":{ backgroundColor:"#fff" } "#label": { width: Ti.UI.SIZE, color: "#222", top:"50%" }
最後に最近参考にした情報のまとめ
Alloy関連の情報は結構色々ネット上にあるのですが、これまとまっていたら嬉しいと思う人が結構いそうなので、とりあえず以下に箇条書きでまとめておきました
- サンプルアプリ
- Aaron Saundersさんが作ったシンプルなやつ
- 作られた時期が古いのでAlloy.getController()とかなってるので利用には注意が必要。
- Aaron Saundersさんが作ったシンプルなやつ
- Alloy全般
- Alloy Framework のドキュメントの日本語訳です。
- これは本当に凄い!
- Alloy Framework のドキュメントの日本語訳です。
ナビバー関連の
その他開発する上で効率化につながる情報
- Titanium×Alloy×CoffeeScript×Jadeでいいんじゃーね
- 元々、TitaniumのClassicの方でCoffeeScritpで書いていたので、その流れでAlloyも効率的にCoffeeで書けるならと思って見つけたページ。しかもJade(いっつも読み方わからないけど、ジェードっていうのかな?)が使えるなら、最近Node.js由来の技術を多用してる自分としてもありがたい
- gitTio
- Titanium Modulesとか Alloyの Widgetsの検索&インストールを簡単に行えるnpmモジュール。詳しくはgitTio - Titanium用モジュール/Alloyウィジェット管理ツールが参考になると思います
- Titanium×Alloy×CoffeeScript×Jadeでいいんじゃーね