このドキュメントではSencha Touchの始め方について解説していきます。 最初にタッチ型端末向けのWebアプリケーションを開発するための基本的なステップについての説明、 次に、Sencha Touchパッケージにも同梱されているデモアプリGeoTweetsの作り方についての詳細な説明 をしていきます。
このドキュメントはSencha Touchを使ってタッチ型端末向けのWebアプリケーションの開発をしたい Web開発者に向けたものです。前提条件としては、Sencha Touchライブラリをダウンロードしていること、 Webサーバー環境が用意されていること、そしてJavaScript・HTML・CSSなどのWebアプリケーション開発 に必要な技術や考え方について理解していること、があげられます。
このドキュメントは以下のセクションで構成されています:
Sencha Touchはタッチ型端末向けWebアプリケーションを開発するためのJavaScriptライブラリです。 Sencha Touchを使えば、エレガントかつ一貫したユーザー体験を、今持っているスキルと最小限 の努力 だけで作り出す事ができます。Sencha TouchではHTMLやCSSといった技術だけを使って(プラグイン無しに) ネイティブアプリケーション並のユーザー体験を生み出します。
Sencha Touchを使ったタッチ型端末向けJavaScriptアプリの開発は以下のステップに分けられます:
開発用のエディタを使ってアプリケーション用のHTMLファイルを作成します。 作成するHTMLファイルの例としては、詳細ステップ:HTMLファイルを作成を参照してください。
アプリケーション用HTMLファイルの中で以下のリンクを指定します:
おすすめのバージョンは:
作成したHTMLファイルを適当な名前、myapp.htmlなどで保存してください。 アプリケーションコードが完成してテスト用サーバーにアップした後、Webブラウザでこのファイルを開き、 アプリケーションの稼働、テストを行います。
アプリをテストするには:
アプリケーションのテストが終わったら、アプリケーションのHTMLファイルがSencha Touchライブラリの 本番用バージョンにリンクするように修正します。そのためには:
<!-- Ext Touch JS -- > <script type="text/javascript" src="../../ext-touch-debug.js" > </script >
アプリケーションのリリース準備が完了したら、アプリケーションのファイルと関連する全てのファイルを本番用の Webサーバーにアップロードするだけです。
このセクションでは前のセクションで説明した各ステップをステップバイステップで詳しく説明していきます。 このセクションで利用するデモアプリ、GeoTweetsのソースコードはSencha Touchパッケージの/examples/guide の中に格納されています。
GeoTweetsは、Sencha Touchを使えば簡単にパワフルなアプリケーションが作れることがよく分かるデモアプリです。 このアプリでは:
以下のセクションではアプリケーション用のHTMLとJavaScriptファイルを細かいステップに分けて説明していきます。
Sencha Touchアプリケーション開発の最初のステップは、Sencha TouchとアプリのCSSファイル、 Sencha TouchとアプリのJavaScriptファイルへのリンクを記述したHTMLファイルの作成です。
GeoTweetsのHTMLファイル名はindex.html、その中身は以下の通りです:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GeoTweets</title >
<!-- Ext Touch CSS -- >
<link rel="stylesheet" href="../../resources/css/ext-touch.css" type="text/css">
<!-- カスタムCSS -- >
<link rel="stylesheet" href="css/guide.css" type="text/css">
<!-- Google Maps JS Touch JS -- >
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"> </script>
<!-- Ext Touch JS -- >
<script type="text/javascript" src="../../ext-touch-debug.js"> </script>
<!-- アプリケーション JS -- >
<script type="text/javascript" src="src/index.js"> </script>
</head>
<body> </body>
</html>
GeoTweetsのHTMLファイルは4つのファイルにリンクします:
CSSファイルの中身についてはそれ自身が非常に分かりやすいため、ここでは詳しくは説明しません。 また、ここでは読者がCSS等のWebアプリケーションを構成する考え方について理解していることを前提としています。
デバッグ用バージョンは圧縮されておらず、ソースコード内のコメントも削除されていません。これはエラーが発生した際に、 どこでエラーが起きているが明確にわかるため、大変役に立ちます。リリース時には通常、本番用に最適化されたext-touch.jsを使用することになります。
注意: <body>タグに中身がないことに注意してください。これはSencha TouchがJavaScriptを介して自動的にページの中身を生成することになるからです。
HTMLファイルを作成したら、次にJavaScriptファイルを作成します。このセクションではアプリケーションの JavaScriptファイル中身を各ステップに分けて説明していきます。
GetTweetアプリケーションのJavaScriptファイルはindex.jsという名前にになります。 ソースコードは以下の通り:
Ext.setup({
icon: 'icon.png',
glossOnIcon: false,
onReady: function() {
var timeline = new Ext.Component({
title: 'Timeline',
cls: 'timeline',
scroll: 'vertical',
tpl: [
'<tpl for=".">',
'<div class="tweet">',
'<div class="avatar"><img src="{profile_image_url}" /></div>',
'<div class="tweet-content">',
'<h2>{from_user}</h2>',
'<p>{text}</p>',
'</div>',
'</div>',
'</tpl>'
]
});
var map = new Ext.Map({
title: 'Map',
getLocation: true,
mapOptions: {
zoom: 12
}
});
var panel = new Ext.TabPanel({
fullscreen: true,
animation: 'slide',
items: [map, timeline]
});
var refresh = function() {
var coords = map.geo.coords;
Ext.util.JSONP.request({
url: 'http://search.twitter.com/search.json',
callbackKey: 'callback',
params: {
geocode: coords.latitude + ',' + coords.longitude + ',' + '5mi',
rpp: 30
},
callback: function(data) {
data = data.results;
// タイムラインのツイートを更新
timeline.update(data);
// 地図にマーカーを追加
for (var i = 0, ln = data.length; i < ln; i++) {
var tweet = data[i];
// If the tweet is geo-tagged, use that to display marker
if (tweet.geo && tweet.geo.coordinates) {
var position = new google.maps.LatLng(tweet.geo.coordinates[0], tweet.geo.coordinates[1]);
addMarker(tweet, position);
}
}
}
});
};
// 以下は全てGoogle MapsのAPI
var addMarker = function(tweet, position) {
var marker = new google.maps.Marker({
map: map.map,
position: position
});
};
map.geo.on('update', refresh);
var tabBar = panel.getTabBar();
tabBar.addDocked({
xtype: 'button',
ui: 'mask',
iconCls: 'refresh',
dock: 'right',
stretch: false,
align: 'center',
handler: refresh
});
}
});
GeoTweetsアプリのJavaScriptコードは以下のことを定義します:
注意:このアプリケーションでは、各コンポーネントを以下の方法で生成しています:
var objectName = new Ext.ComponentName({
objectDefinition
});
それぞれの意味は:
以下のセクションではアプリケーションスクリプトを書いていく際の細かなステップについて解説していきます。
開発用のエディターでGeoTweetsのアプリケーションスクリプト(index.js)を書き始めましょう。 最初のコードは次のようになります:
Ext.setup({
icon: 'icon.png',
glossOnIcon: false,
onReady: function() {
Ext.setupメソッドはHTMLページをタッチ端末で利用できるように設定します。このメソッドではアプリケーション 起動時の各種プロパティや挙動を設定することができます。このメソッドを含むSencha Touch APIの詳細については Sencha Touch APIドキュメント(英語)を参照してください。
GeoTweetsアプリケーションでは以下の起動プロパティを設定しています:
onReadyメソッドで指定した関数の中で、残りのアプリケーションコードを定義していきます:
timelineカードはツイートをリスト形式で表示します。このカードはExt.Componentのオブジェクト として生成されます。Ext.Componentはデータ、他のコンポーネント、ウィジェットを表示するための最も基本的なクラスです。
Ext.Componentオブジェクトであるtimelineカードを生成するコードは以下の通りです:
var timeline = new Ext.Component({
title: 'Timeline', // タブ部分に表示されるタブ名
cls: 'timeline', // timeline内の要素のスタイルを指定するためのCSSクラス
scroll: 'vertical', // 縦方向にスクロール可能にする
tpl: [ // ツイートデータの表示用テンプレート
'<tpl for=".">',
'<div class="tweet">',
'<div class="avatar"><img src="{profile_image_url}" />', </div> // つぶやいた人の写真
'<div class="tweet-content">',
'<h2>{from_user}</h2>', // つぶやいた人の名前
'<p>{text}</p>', // つぶやき
'</div>',
'</div>',
'</tpl>'
]
});
Ext.Componentオブジェクトであるtimelineカードでは:
このテンプレートはTwitterから取得したデータをもとにtimlineカードの中身を書き換えます。 テンプレートに紐付けられるデータは中括弧({})で囲われます。今回の場合は、 profile_image_url、from_user、 そしてtextで、これらはTwitterのデータが格納されているJSONの内のプロパティ名と一致しています。 データそのものは、後述のExt.util.JSONP.requestメソッドで取得します。
timelineカードのテンプレートは以下の通りです:
tpl: [ // ツイートデータの表示用テンプレート
'<tpl for=".">',
'<div class="tweet">',
'<div class="avatar"><img src="{profile_image_url}" />', </div> // つぶやいた人の写真
'<div class="tweet-content">',
'<h2>{from_user}</h2>', // つぶやいた人の名前
'<p>{text}</p>', // つぶやき
'</div>',
'</div>',
'</tpl>'
]
アプケーション用のCSSファイル、guide.css、を編集することで上記のテンプレートコードが実際の画面上で どのように表示されるかを指定・変更することができます。
下記の画像はtimelineカードの表示例です
mapカードは現在地周辺のツイートを地図上に表示します。
Ext.Mapのオブジェクトであるmapカードのコードは以下の通りです:
var map = new Ext.Map({
title: 'Map', // タブ部分に表示されるタブ名
getLocation: true, // ユーザーの現在地情報を取得
mapOptions: { // 地図の描画オプション
zoom: 12
}
});
Ext.MapはGoogle MapコンポーネントをExt.Componentでラップしたコンポーネントです。 他のExtのコンポーネントと同様に、Ext.Mapではカードの見た目を設定するためのプロパティが設定 できます:
Ext.Mapは他にも地図を描画する際のオプションとしてmapOptionsを指定できます。Ext.Map に渡すmapOptionsは実際にはGoogle Mapオブジェクトにそのまま渡されることになります。Google Maps APIに 関する詳しい情報についてはGoogle Maps API Documentationを参照してください。
このアプリでは、zoomオプションを使って、地図のズームレベルの初期値として12を設定しています。
下記の画像はmapカードの表示例です:
Ext.TabPanelはアプリケーションで表示する複数のオブジェクトを格納しておくためのコンポーネントです。 今回の例では、TabPanelは既に定義されている2つのコンポーネント、timelineと mapを格納し、さらにそれぞれのコンポーネントのtitleプロパティで定義された値を表示 するタブをカードの上部に自動的に追加します(TimelineとMap)。各タブ間の 切り替えのためのロジックは自動的に提供されます。
Ext.TabPanelのコードは以下の通り:
var panel = new Ext.TabPanel({
fullscreen: true, // 画面の一部ではなく全てを占有
cardAnimation: 'slide', // カードを切り替える際のアニメーション効果
items: [timeline, map] // TabPanelに格納するコンポーネント(カード)
});
TabPanelでは見た目および挙動の設定のため3つのプロパティを設定しています:
下記の画像はカードの切り替え時のアニメーション効果の例です:
カードの切り替えには他にもflip、wipe、cube、popなどのアニメーション効果が利用できます。 より詳細な内容についてはAPIドキュメント の Ext.animsクラスを参照してください。
refresh関数はアプリケーションが起動した際に呼ばれ、また、refreshボタンがタップされた際にも呼び出されます。 この関数はTwitterからデータを取得するために外部のサーバーに対してリクエストを行います。さらにrefresh関数はその内部で addMarkerを呼び出し地図上にツイートの位置を表示させます。
refresh関数のコードは以下の通りです:
var refresh = function() { // refresh関数を定義
var coords = map.geo.coords; // Geolocation機能から現在地の緯度経度を取得
Ext.util.JSONP.request({ // JSONPを使って外部サーバーへリクエスト
url: 'http://search.twitter.com/search.json', // リクエストを送るURL
callbackKey: 'callback', // Twitter APIの呼び出しに必要なコールバックパラメーター
params: {
geocode: coords.latitude + ',' + coords.longitude + ',' + '5mi', // 現在地の緯度、経度、取得対象半径を指定
rpp: 30 // 1回のリクエストで取得するツイート数
},
callback: function(data) { // Twitter APIからの戻り値を格納する仕組みを定義
data = data.results; // Twitter APIからの戻り値を変数dataに格納
timeline.update(data.results); // timelineカードのツイートを更新
for (var i = 0, ln = data.length; i < ln; i++) { // mapカードにポイントを追加するためのループ
var tweet = data[i]; // 個別のツイートデータを取得
if (tweet.geo && tweet.geo.coordinates) { // ツイートに位置情報が付属していた場合のみ処理
var position = new google.maps.LatLng(tweet.geo.coordinates[0], tweet.geo.coordinates[1]); // 緯度経度を取得
addMarker(tweet, position); // 新しいデータをaddMarker関数を使って表示
}
}
}
});
};
Ext.util.JSONP.requestを使うとTwitter APIへのJSONコールを簡単に行えます。このメソッドへ渡すパラメーターは:
url: 'http://search.twitter.com/search.json',
params: {
geocode: coords.latitude + ',' + coords.longitude + ',' + '5mi',
rpp: 30
今回の周辺のツイート検索で利用したパラメーターは:
注意:geocodeとrppTwitter Search APIで定義されているパラメーターです。
callback関数はTwitterからの戻り値を受け取り、それを変数dataに格納しています。 この関数では最初にtimelineのupdateメソッドを呼び出して新しいツイートのリストに更新しています。 タイムラインカードを定義のセクションで定義したテンプレートが{profile_image_url}、 {from_user}、{text}に紐付けられていましたが、これらのデータは全てTwitterからの戻り値内で定義されています。
callback関数の中身は以下の通り:
callback: function(data) {
data = data.results;
timeline.update(data.results);
Twitter APIからの戻り値は以下のような構造になっています:
{"results":
[{"profile_image_url":""http://a1.twimg.com/profile_images/704555348/boat3_normal.jpg...
"from_user":"jonathanjulian",...
"text":"@agnellvj have a look at the most intense #extjs book to be published do far!",
...
forループ内では取得したTwitterデータの1件1件に対して位置情報の有無を確認しています。 ツイートに位置情報が含まれていた場合、その緯度経度情報をpositionに格納され、地図にツイート の位置を表示するための関数addMarkerに渡されます。
対応するコードは以下の通り:
for (var i = 0, ln = data.length; i < ln; i++) {
var tweet = data[i];
if (tweet.geo && tweet.geo.coordinates) {
var position = new google.maps.LatLng(tweet.geo.coordinates[0], tweet.geo.coordinates[1]);
addMarker(tweet, position);
addMarker関数は渡された位置情報に基づいてツイーとを地図上にマッピングします。この部分のコードの 大半はGoogle Maps API関連のコードで、 Sencha Touch APIのコードではありません。
対応するコードは以下の通り:
var addMarker = function(tweet, position) { // addMarker関数を定義
var infowindow = new google.maps.InfoWindow({ // データを表示するための吹き出しを定義
content: '<h2>' + tweet.from_user + '</h2><p>' + tweet.text + '</p>' // 表示するデータのHTMLを定義
});
var marker = new google.maps.Marker({ // マーカーを定義
map: map.map,
position: position,
clickable: true
});
infowindow.open(map.map, marker); // マーカーを地図に表示
}
refresh関数は、mapカード内部のGeolocationが更新される毎に作動します。 mapカードの生成の際にgetLocation:trueを指定しているため、refresh関数はページが ロードされ、ユーザーの現在地情報を取得した直後に呼び出されます。
refresh関数を起動するためのイベントを定義しているコードは下記の通り:
map.geo.on('update', refresh);
注意:Twitter APIではデータの更新はリアルタイムではなく一定の間隔で行われるため、通常はキャッシュされた データが返されます。つまり、ユーザーが更新ボタンをタップする毎に最新のツイートが表示されるわけではありません。
TabBarに更新ボタンを追加するためには、まずTabPanelのTabBar部分を下記のコードで取得します:
var tabBar = panel.getTabBar();
下記の画像に表示されているのがTabBar部分になります:
このセクションではGeoTweetアプリのTabBarのドッキングアイテムとして更新ボタンを追加するテクニックを解説します。
TabBarにボタンを追加するには、addDockedメソッドに直接ボタン生成用のオブジェクト(オブジェクトリテラル) を渡すだけです。このオブジェクト内でxtypeプロパティを指定してあげるだけで、目的のオブジェクトをその場で 生成することができます。xtypeを使ったオブジェクト生成はSencha Touchライブラリのあらゆるところで見かける ことになると思います。コンポーネントやウィジェッットを挿入したい任意の場所において、xtypeプロパティとその他の 設定用プロパティが設定されたオブジェクトリテラルを使うことが可能です。しかしながら、このテクニックは簡単にインターフェース を作ることはできるのですが、保守性の面では若干劣ることもあります。
tabBar.addDocked({
xtype: 'button', // Ext.Buttonクラスのインスタンスを生成することを指定
ui: 'plain', // 外観の設定、他には"light"、"dark"なども指定可能
text: 'refresh', // ボタンのinnerHTMLに使われる文字列
iconCls: 'refresh', // ボタンの背景画像設定に使われるCSSクラス
dock: 'right', // ボタンをTabBarの右側に配置
stretch: false, // ボタンがTabBarの高さ一杯に広がるのをキャンセル
align: 'center', // ボタンをTabBarの縦方向の中心に配置
handler: refresh // ユーザーがボタンをタップした際の処理
});
ドッキングアイテムのレイアウトを指定するにはいくつかのプロパティを指定する必要があります。 GeoTweetsでは以下のプロパティを利用しています:
そして最後に指定するのが、ユーザーがボタンをタップした際の処理を指定するhandler関数です。GeoTweetsアプリケーション ではボタンがタップされた場合にはrefresh関数を呼び出します。この処理を行うためのコードは下記の通りです:
handler: refresh
下記の画像が今回定義したボタンになります:
アプリケーション用JavaScriptファイルのコーディングが完了したら次はテストです。アプリをテスト を参照してテストを行ってください。
アプリのテストが完了したら、 リリース用にアプリを修正を参照して Sencha Touchライブラリをデバッグ用から本番用に差し替えます。
アプリケーションのリリース準備が整ったら アプリをリリースを参照して リリース作業を行ってください。
ここまで見てきた通りSencha TouchでのWebアプリケーションの開発は迅速かつ簡単に行えます。 Sencha Touchのパッケージにはこの他にもたくさんのでもアプリケーションが同梱されていますので、 これらを参考にSencha Touchの使い方を学んでください。
このドキュメントでカバーされたトピックについての詳細は、下記の情報源を参照してください:
最終更新日2010/06/21、 日本語訳 Ext Japan, LLC、株式会社sus4