Alloyに自作ライブラリを組み込んで利用する方法
スライドメニューの実装が出来たので、Alloyでもう少しアプリっぽいものを作ろうと考えてる人の参考になりそうなものを考えてみました。
本来なら、Alloy標準機能のModelの機能を紹介したい所なのですが、まだそっちはあまり本格的にいじれてないのと、外部のライブラリを手軽に使う方法をたまたま公式ドキュメントを見てて知ったので今回はそれについて紹介することにします。
- 目次
CommonJSスタイルのライブラリは、app/lib配下に置けば手軽に利用できる
どういうことかというAlloyのappディレクトリ配下にlibというフォルダを作成して、組み込みたいCommonJSのライブラリを配置すればOKです
私が作ったNHK番組表APIにアクセスするファイルをGitHubにアップしてあるのですが、TitaniumのClassicの環境で利用することを想定して、別途Moment.jsとかUnderscore.jsの読み込みを工夫してある実装になってます。 Alloyは標準でMoment.jsとかUnderscore.jsが使えるので、少しだけ手直ししたやつをGistに貼ったのでこれをダウンロードをダウンロードして、libフォルダ配下に配置します。
最終的にこのようになればOKです
. ├── README ├── alloy.jmk ├── alloy.js ├── assets │ ├── android │ ├── blackberry │ ├── iphone │ ├── mobileweb │ └── tizen ├── config.json ├── controllers │ └── index.coffee ├── lib/ │ └── nhk.js ├── models/ ├── styles/ │ └── index.tss ├── views/ │ ├── index.xml │ └── index.jade └── widgets/
ライブラリの配置が完了したので、実際にサンプルとなるアプリケーションを作っていきます。
まずはベースとなるUIを考える
ライブラリを利用する前に、まずは controller,view,styleの定義を行います。
前回作ったスライドメニューを流用してひとまずこのようなUIにしました。
ソースコード
上記実現するソースコードを以下しめします
index.jade
Alloy TabGroup Tab#tabOne Window#mainWindow.container(title="main") LeftNavButton(platform="ios") Button#showBtn(title="MENU") TableView#mainMenu TableView#subMenu TableViewRow.row(title="本日の番組") TableViewRow.row(title="昨日の番組") TableViewRow.row(title="エリアを選択する")
index.coffee
$.index.open() $.showBtn.addEventListener 'click', (e) -> slide() slide = (e) -> if $.mainMenu.slideState is false leftPosition = 200 $.mainMenu.slideState = true else leftPosition = 0 $.mainMenu.slideState = false transform = Titanium.UI.create2DMatrix() animation = Titanium.UI.createAnimation() animation.left = leftPosition animation.transform = transform animation.duration = 300 $.mainMenu.animate(animation)
index.tss
".container": { backgroundColor:"#f9f9f9" }, "#mainWindow":{ statusBarStyle:0, tabBarHidden:true, slideState:false, backgroundColor:"#f9f9f9" } "#mainMenu":{ width:Ti.UI.FULL, height:Ti.UI.FULL, backgroundColor:"#eeeeee", separatorColor:"#ededed", top:0, left:0, zIndex:2, slideState:false } "#subMenu":{ width:200, height:Ti.UI.FULL, backgroundColor:"#cccccc", separatorColor:"#cdcdcd", top:0, left:0, zIndex:1 } ".row":{ backgroundColor:"#cccccc", width:Ti.UI.FULL, height:40 }
ベースとなるUIが出来たので、これ以降でlib配下のライブラリを読み込んで実際にNHK番組表APIにアクセスする手順を解説します
NHK番組表APIにアクセスする
Menuボタンをタッチすると、いくつか項目が表示されてその中の「本日の番組」という項目がクリックされた時に番組表情報を取得することを念頭に実装をしていきます
基本的にはControlの修正がメインになってきます
「本日の番組」という項目を得るために、$.subMenuにイベントリスナーを設定
$.subMenuはTableViewとして定義しておりe.indexの値をチェックすることで何番目の項目がクリックされたかわかります。
「本日の番組」は一番先頭なので、「0」になるため controllers/index.coffee に以下のように記述します
$.subMenu.addEventListener 'click', (e) -> if e.index is 0 Ti.API.info "本日の番組情報を取得します"
というような形になります
NHK番組表APIのライブラリ利用の準備
nhk.jsはMoment.jsに依存してるため、Alloy標準で組み込まれてるMoment.jsを利用するための宣言を最初に行いつつ、ライブラリの読み込み、初期化処理をするためcontrollers/index.coffee に以下のように記述します。
moment = require('alloy/moment') NHKProgram = require("nhk") config = apikey:"YOUR API KEY" client = new NHKProgram(config) area = '東京' service = "NHK総合1"
本日の番組がクリックされた時に実際にNHK番組表APIにアクセスして情報更新する
私が作ったライブラリは
client.list("エリア名", "サービス名","日付",callback関数)
という感じで利用します。
具体的には
$.subMenu.addEventListener 'click', (e) -> if e.index is 0 Ti.API.info "本日の番組情報を取得します" todayDate = moment() client.list area,service,todayDate,(result) -> # result.list.g1 の配列に番組に関する情報が格納されているため # for program in result.list.g1 のようにして # 必要な情報を得る
という感じになります。
最終的な形
controllers/index.coffeeは最終的にはこのようになります。
moment = require('alloy/moment') NHKProgram = require("nhk") config = apikey:"YOUR API KEY" client = new NHKProgram(config) area = '東京' service = "NHK総合1" $.showBtn.addEventListener 'click', (e) -> slide() $.subMenu.addEventListener 'click', (e) -> if e.index is 0 todayDate = moment() client.list area,service,todayDate,(result) -> rows = [] for program in result.list.g1 row = Ti.UI.createTableViewRow width:Ti.UI.FULL height:80 backgroundColor:"f3f3f3" programID:program.id title = Ti.UI.createLabel width:220 height:50 top:5 left:70 textAlign:'left' color:"#222" font: fontSize:14 fontWeight:'bold' text:"#{program.title}" subtitle = Ti.UI.createLabel width:220 height:20 top:55 left:70 textAlign:'left' color:"#999" font: fontSize:12 text:"#{program.subtitle}" timeTable = Ti.UI.createLabel width:60 height:20 top:20 left:5 color:"#007FB1" font: fontSize:12 fontWeight:'bold' text:"#{moment(program.start_time).format('HH:mm')}〜" row.add title row.add subtitle row.add timeTable rows.push row slide() return $.mainMenu.setData rows slide = (e) -> if $.mainMenu.slideState is false leftPosition = 200 $.mainMenu.slideState = true else leftPosition = 0 $.mainMenu.slideState = false transform = Titanium.UI.create2DMatrix() animation = Titanium.UI.createAnimation() animation.left = leftPosition animation.transform = transform animation.duration = 300 $.mainMenu.animate(animation) $.index.open()
Alloyの流儀に従ってUI要素の処理をStylesにうつす
これでも動作するのですが、controllerの中で、UIに関する処理をしてるのがちょっと気持ち悪いので、番組表取得した所のUIの組み立ての処理を一部見直します。
Alloyには、Dynamic Stylesという仕組みがあるのでそれを利用して
- styles/index.tssに、それぞれのUI要素の色、幅、高さの情報を定義
- controllers/index.coffeeでのTableViewRowの組み立て時には、上記styles/index.tssで定義したものを反映させる
ということを行います。
styles/index.tssの修正
以下内容を追記します
".programRow":{ width:Ti.UI.FULL, height:80, backgroundColor:"f3f3f3" } ".programTitle":{ width:220, height:50, top:5, left:70, textAlign:'left' color:"#222", font:{ fontSize:14 fontWeight:'bold' } } ".programSUbTitle":{ width:220, height:20, top:55, left:70, textAlign:'left', color:"#999", font:{ fontSize:12 } } ".programTimeTable":{ width:60, height:20, top:20, left:5, color:"#007FB1", font:{ fontSize:12 fontWeight:'bold' } }
controllers/index.coffeeの修正
for program in result.list.g1 row = $.UI.create 'TableViewRow', programID:program.id classes:"programRow" title = $.UI.create 'Label', text:"#{program.title}" classes:"programTitle" subtitle = $.UI.create 'Label' , text:"#{program.subtitle}" classes:"programSubTitle" timeTable = $.UI.create 'Label', text:"#{moment(program.start_time).format('HH:mm')}〜" classes:"programTimeTable"
パッと見わかりづらいかと思いますが、先程までは
Ti.UI.createTableViewRow width:xxx
としていた処理を
$.UI.create 'TableViewRow', classes:"programRow"
のように、$.UI.create "要素名",
というような形にしてます。
まとめ
Alloyに自作ライブラリを組み込んで利用する方法を紹介しました。今回紹介したNHK番組表APIのようなWebAPI利用するアプリケーションをTitaniumで作る場合に、Titanium のClassicの環境でももちろん出来るのですが、Alloy使うことでより構造化したアプリケーションになると思います。