Monaca入門:Onsen UI+AngularJSで作るハイブリッドモバイルアプリ(2)
Monacaで作る、初めてのOnsen UIアプリ
新規作成した“初めてのOnsen UIアプリ”プロジェクトの各ファイルをAngularJS流に書き換える。そのアプリをデバッグビルドし、デバイスに実際にインストールする。
連載2回目の今回は、前回作成した“初めてのOnsen UIアプリ”プロジェクトを開いて、そこに含まれるファイルの中身を見ていく。
「Onsen UI最小限のテンプレート」から作成したこのプロジェクトには、自動的に作成されるナビゲーションやボタン用のコンポーネントが含まれ、コードは通常のJavaScriptの書き方で書かれている。これをAngularJS流に書き換えていく。そして書き換えたアプリのアプリケーションファイルを作成(ビルド)して、デバイスに実際にインストールする。
Monacaにログインしていない場合には、トップページを開いて、[ログイン]ボタンからログインする。するとMonaca IDEのダッシュボードが開き、プロジェクトの一覧に“初めてのOnsen UIアプリ”が表示される。このプロジェクトを開くにはプロジェクト名の右にある[開く]ボタンをクリックする。Monaca IDEがプロジェクトを開き、左のプロジェクトパネルにプロジェクトに含まれるフォルダーやファイルをツリー状に表示する。右のコードエディターにはindex.htmlファイル(や前回開いていたファイル)が開かれる。
“初めてのOnsen UIアプリ”を起動
まずは“初めてのOnsen UIアプリ”を実行して、動作を確認してみよう。
アプリを実行するには、デバイスにインストールしたMonacaデバッガーを起動する。するとメールアドレスとパスワードを入力するテキストフィールドが表示されるので、Monacaに登録したユーザーアカウントとパスワードを入力して、[ログイン]ボタンをタップする。ログインに成功すると、デバッガーのプロジェクト一覧が表示される。このリストから実行したいプロジェクト名をタップする。なおデバッガーからログアウトするには、デバッガーのプロジェクト一覧画面の左下にあるユーザー名のタップで表示されるボックスから[ログアウト]を選択する。
“初めてのOnsen UIアプリ”が起動すると、図2-1の左に示す画面が表示される。これはプロジェクトパネルのwwwフォルダーにあるpage1.htmlファイルから作成された画面だ。上部には[Navigator]と書かれたバーがあり、その下には[Push Page2]ボタンがある。またページ右下には前回紹介したデバッガーのメニューボタンがある。
[Push Page2]ボタンをタップすると、図2-1の右に示す画面に移動する。これはwwwフォルダーにあるpage2.htmlファイルから作成された画面だ。ここは[Page 2]と書かれたバーがあり、その左には[Back]ボタンがある。バーの下には[Page 2]という文字と[Pop Page]ボタンがある。[Back]か[Pop Page]ボタンをタップすると、前のpage1.htmlの画面に戻る。
ボタンのタップでページが変わるときにはアニメーションが伴っている。例えばpage1からpage2に進むときには、page1の画面が左にスライドして消え、同時に右からpage2がスライドして現れる。実は「Onsen UI最小限のテンプレート」には、初めからこのナビゲーションとアニメーションの機能が含まれている。
ファイルの中身を探る
ではMonaca IDEに戻り、今確認した“初めてのOnsen UIアプリ”を構成する“初めてのOnsen UIアプリ”プロジェクトのファイルを見ていこう。
index.htmlファイル
Monacaアプリでは、Webページを作成するのと同じ要領でアプリのファイルを作成する。その大元になるのがwwwフォルダーにあるindex.htmlファイルだ。ここではアプリに必要な各種ファイルの読み込みや、「Onsen UI最小限のテンプレート」の場合にはナビゲーション用のコンポーネントを使ってpage1.htmlを読み込む作業が行わる。アプリの動作を決めるJavaScriptコードもここに記述する。
index.htmlが開かれていない場合には、プロジェクトパネルで[index.html]をダブルクリックする。するとコードエディターにそれが開かれる。index.htmlが開かれていてコードエディターに別のページが前面に表示されている場合には、コードエディター上部にある[index.html]タブをクリックする。
index.htmlファイルには次のコードが書かれている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<script>
ons.bootstrap();
ons.disableAutoStatusBarFill(); // (Monaca enables StatusBar plugin by default)
</script>
</head>
<body>
<ons-navigator title="Navigator" var="myNavigator" page="page1.html">
</ons-navigator>
</body>
</html>
|
ここで注目してほしいのは5行目のコードだ。
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">
ここではviewportメタタグを使って表示領域をデバイスの幅と高さに設定し、初期と最大の表示倍率を「1」、ユーザーのズーム操作を許可しない、という設定を行っている。viewportメタタグのこの設定によって、このアプリはモバイルデバイスの画面で適切に表示されるようになる。
その下にはOnsen UIコンポーネントの読み込みで必要なJavaScriptファイルとCSSファイルが読み込まれている。cssフォルダーにあるstyle.cssは、このアプリに使用するCSSファイルだ。自分でCSSを記述するときにはこのファイルに書き込む。
<script>タグには次の行がある。この呼び出しによってOnsen UIコンポーネントが読み込まれる。
ons.bootstrap();
<body>タグには次の2行が書かれている。
<ons-navigator title="Navigator" var="myNavigator" page="page1.html">
</ons-navigator>
<ons-navigator>
というのはOnsen UIのコンポーネントの1つで、ページのナビゲーションを管理、制御する。Onsen UIコンポーネントは、HTMLと同じタグ形式でHTMLファイル内に記述していく。title
やvar
、page
は<ons-navigator>
の属性だ。var
にはJavaScriptコードからこの<ons-navigator>
コンポーネントを参照するための名前を指定する。page
属性には<ons-navigator>
で最初に表示するHTMLページを指定する。“初めてのOnsen UIアプリ”を起動して最初にpage1.htmlが表示されたのは、page
属性に「page1.html」が指定されていたためだ。
<ons-navigator>
コンポーネントによってpage1.htmlが読み込まれたので、次はpage1.htmlファイルを見ていこう。
page1.htmlファイル
プロジェクトパネルでwwwフォルダーにある[page1.html]をダブルクリックし、コードエディターでこれを開く。
page1.htmlには次のコードが書かれている。<ons-
で始まるのがOnsen UIのコンポーネントだ。
<ons-page>
<ons-toolbar>
<div class="center">Navigator</div>
</ons-toolbar>
<div style="text-align: center">
<br>
<ons-button
onclick="myNavigator.pushPage('page2.html')">
Push Page 2
</ons-button>
</div>
</ons-page>
|
ここではOnsen UIコンポーネントのタグの包含構造に注目してほしい。<ons-page>
コンポーネントが全体を包んでおり、<ons-toolbar>
/<div>
/<ons-button>
要素が、<ons-page>
の中にある。
<ons-page>
はアプリのページ、つまり画面を表すコンポーネントで、コンテナー(=入れ物)の役割を果たす。
その中に含まれる<ons-toolbar>
は画面上部にツールバーを表示するためのコンポーネントだ。内部にはツールバー用のボタンやページタイトル用の<div>
要素を含むことができる。“初めてのOnsen UIアプリ”の最初の画面で、バーに[Navigator]と表示されていたのはこの<div class="center">Navigator</div>
だ。
<ons-toolbar>
の下には<div>
があり、その中には<ons-button>
がある。これは“初めてのOnsen UIアプリ”の最初の画面で表示された[Push Page2]ボタンだ。ここではこのボタンのタップで(=onclick
属性で)、myNavigator.pushPage('page2.html')
という命令が実行されるようになっている(皆さんの予想通り、このボタンのタップでpage2に進んだのは、この命令が実行されたためだ)。
「myNavigator」は、index.htmlファイルの<ons-navigator>
のvar
属性で指定した<ons-navigator>
の名前だ。<ons-navigator>
のvar
属性に名前を指定しておくと、アプリのどの場所からでもこの<ons-navigator>
の機能を呼び出すことができる。
pushPage()
は<ons-navigator>
の関数で、指定されたHTMLページを読み込み、それを画面に表示する。
<ons-navigator>
からここまでの包含関係を図で表すと、図2-2のようになる。<ons-page>
はコンテナ用のコンポーネントで、今はその中に<ons-toolbar>
や<div>
、<ons-button>
を含んでいる。そして<ons-navigator>
が、ページを構成するこの基本構造を含んでいる、という関係だ。
<ons-navigator>
はスタックと呼ばれる層の積み重ねでページを管理する。図2-3を見てほしい。<ons-navigator>
は最初ページ1だけを含む。これは図2-2の状態だ。
ここで[Push Page2]ボタンがタップされると、<ons-navigator>
のpushPage('page2.html')
が呼び出されるので、<ons-navigator>
はpushPage()
関数の引数に指定されたページ2をページ1の上からプッシュする(=押し下げる)。このプッシュによってページ2がスタックの最上位に来て、これが画面に表示される。
ページ2のボタンで<ons-navigator>
のpopPage()
関数が呼び出されると(実際、page2.htmlファイルに記述されている)、<ons-navigator>
はスタックの最上位にあるページをポップして(=跳ね上げて)これを消去する(実際にスタックから失われる)。これによりページ1がスタックの最上位に来て、アプリの画面にはこれが表示される。
<ons-navigator>
はこの方法でページを管理している。この処理方法は後入れ先出し(LIFO)と呼ばれる。
次はpushPage()
に指定されているpage2.htmlファイルを見ていこう。
page2.htmlファイル
プロジェクトパネルで[page2.html]をダブルクリックして開くと、コードエディターに次のコードが表示される。
<ons-page>
<ons-toolbar>
<div class="left"><ons-back-button>Back</ons-back-button></div>
<div class="center">Page 2</div>
</ons-toolbar>
<div style="text-align: center">
<h1>Page 2</h1>
<ons-button
onclick="myNavigator.popPage()">
Pop Page
</ons-button>
</div>
</ons-page>
|
このページも全体を<ons-page>
コンポーネントが包んでいる。<ons-toolbar>
には1つめの子として<div>
があり、その中に<ons-back-button>
がある。これがpage2.htmlを表示したとき、ツールバーの左にあった[Back]ボタンだ。このボタンには何も命令が書かれていないが、<ons-back-button>
はページを1つ前に戻す機能を持っている。
<ons-toolbar>
の2つめの子要素も<div>
だ。<ons-toolbar>
でこのように<div>
を内部に持たせ、<div>
のclass
属性に「left」や「center」、「right」を指定すると、その<div>
をツールバーの左、真ん中、右に表示することができる。
<ons-toolbar>
の下には<div>
があり、その中には<h1>
と<ons-button>
がある。<ons-page>
にはOnsen UIコンポーネントだけでなく、通常のHTML要素を置くこともできる。<ons-button>
のonclick
属性にはmyNavigator.popPage()
が指定されているので、<ons-navigator>
は前述した方法でページ2をポップする。その結果、ページ1が表示される。
AngularJS流に書き換える
続いて、この“初めてのOnsen UIアプリ”をAngularJS流に書き換えていこう。といっても書き換える場所はごくわずかだ。
この連載で“通常のJavaScript流”と呼んでいる書き方では、AngularJSによって守られているOnsen UIの世界にons
という名前のオブジェクトを通してアクセスする。ons
はいわば、通常のJavaScriptに開かれたOnsen UIへの窓口だ。これに対し、“AngularJS流”の書き方では、この窓口を通す必要がない。コードの書き手である皆さんはOnsen UIの世界に最初から存在できるのだ。
とはいえ、“初めてのOnsen UIアプリ”で記述されているJavaScriptコードは少なく、また<ons-navigator>
のvar
属性を使って行うmyNavigator.pushPage()
やmyNavigator.popPage()
も、ただons.navigator
に置き換えるだけだ。
【コラム】myNavigatorとons.navigator
myNavigator
はすでに述べたように、index.htmlファイルにある<ons-navigator>
のvar
属性に指定されていた名前だ。
JavaScriptコードでこの名前を変数として使用すると、どこからでもこの<ons-navigator>
が参照できる。具体的にいうと、var
属性に指定された名前はwindow
オブジェクトのプロパティとして設定される。これはグローバルな場所なのでどこからでもアクセスできる。
var
属性の使用は非常に便利なように思えるが、実はAngularJS本来の方法ではない。AngularJSではJavaScriptコードをモデル、ビュー、コントローラーに分けて記述するので、無条件にどこからでもアクセスできる状態はAngularJSにそぐわない。この意味でvar
属性はAngularJSのハードルを低くするために設けられた機能だといえる。
一方、AngularJS流の書き方では、同じ<ons-navigator>
をons.navigator
という方法で参照する。これはOnsen UIの提供元によって公開されている<ons-navigator>
の正式の参照方法だ。
AngularJSでは悪い言い方をすると、ちまちま区切られた狭いコントローラーの中で作業を行い、隣のコントローラーの情報を得るにも正式の手続きを踏む必要がある。その状況でアプリのページを管理する<ons-navigator>
にons.navigator
でアクセスできるのは、“天から降りて来た蜘蛛(クモ)の糸”をつかむようなありがたい仕様だ。
ではindex.htmlファイルから見ていこう。
AngularJS流に書き換えた、index.htmlファイル
まず、コード冒頭にある<html>
を<html ng-app="myApp">
に変更する(次のコードを参照)。ng-app
はAngularJSの属性で、AngularJSアプリとしての範囲を指定する。<html>
で使用すると、そのページ全体がAngularJSアプリ、つまりAngularJSの仕組みに従ったアプリとなる。
<!-- ng-app属性を指定-->
<!--<html>-->
<html ng-app="myApp">
|
続いて<script>
タグに記述されているJavaScriptコード2行を削除し、angular.module('myApp', ['onsen']);
を記述する(次のコード)。[]
内の'onsen'
はOnsen UIを構成するモジュールを指している。angular.module()
関数はAngularJSの新しいモジュールを作成する。今の場合では、Onsen UIの機能を持つmyApp
という名前のモジュールが作成される。モジュールとは着脱可能な1つのかたまりのことで、AngularJSではアプリも1つのモジュールであり、追加する機能もモジュールとしてアプリに“注入”する。
// ons.bootstrap();
// ons.disableAutoStatusBarFill(); // (Monaca enables StatusBar plugin by default)
// これに置き換える
angular.module('myApp', ['onsen']);
|
最後に<ons-navigator>
を次のように置き換える。<ons-navigator>
のtitle
属性は事実上機能していないので削除する。またAngularJSではvar
属性は使用しないのでこれも削除する。
<!--ons-navigatorのtitleとvar属性を削除-->
<!--<ons-navigator title="Navigator" var="myNavigator" page="page1.html"></ons-navigator>-->
<ons-navigator page="page1.html"></ons-navigator>
|
index.htmlでの変更は以上だ。
AngularJS流に書き換えた、page1.htmlファイル
page1.htmlファイルでは、<ons-button>
を次のように変更する。AngularJSではonclick
属性ではなくng-click
属性を使用する。また<ons-navigator>
のvar
値のmyNavigator
ではなく、ons.navigator
を使用する。
<!--<ons-button
onclick="myNavigator.pushPage('page2.html')">
Push Page 2
</ons-button>-->
<!--ons-buttonのonclick属性とその値を変更-->
<ons-button
ng-click="ons.navigator.pushPage('page2.html')">
Push Page 2
</ons-button>
|
AngularJS流に書き換えた、page2.htmlファイル
page2.htmlファイルでも同様に、<ons-button>
を次のように変更する。
<!--<ons-button
onclick="myNavigator.popPage()">
Pop Page
</ons-button>-->
<!--ons-buttonのonclick属性とその値を変更-->
<ons-button
ng-click="ons.navigator.popPage()">
Pop Page
</ons-button>
|
“初めてのOnsen UIアプリ”をAngularJS流に書き換える場所は以上だ。Monacaデバッガーからアプリを起動して動作を確認すると、書き換える前と違いがないことが分かる。ここでひとまず休憩しよう。
プロジェクトのエクスポートとインポート
皆さんがこれからMonacaアプロジェクトを作成していくと、実はダッシュボードに置いておけるプロジェクト数の制限に引っかかることになる。
Monaca IDEのダッシュボード上部にある[プラン詳細を見る]リンクをクリックすると分かるが、皆さんが今利用しているプランは無料のBasicだ。Basicプランではダッシュボードの[オンライン]に置いておけるプロジェクト数が3に制限される。もちろんプランを上級のもの(PersonalやGold)にグレードアップすることもできるが、Basicプランのままプロジェクトの作成を継続する方法は2つある。
1つめは、使用しないと分かっているプロジェクトを削除する方法だ。プロジェクトを削除するには、ダッシュボードの一覧にあるプロジェクト名にマウスを重ねる。すると[詳細][お気に入り登録][編集]リンクとギアマークのボタンが現れる。このギアマークをクリックし、表示されるメニューから[プロジェクトを削除]をクリックする(図2-4)。
2つめは、Monaca IDEのエクスポートとインポート機能を利用する方法だ。プロジェクトを保管したいときにはエクスポート機能を使って手元にダウンロードし、必要になったときにインポート機能を使ってIDEに戻す。プロジェクトをエクスポートする(=書き出す)には、プロジェクトを開いた状態で[ファイル]→[エクスポート]を選択する。すると[プロジェクトのエクスポート]が表示されるので(図2-4-A)、タイトルと説明を入力して[エクスポート]ボタンをクリックする。IDEがプロジェクトを1つのZIPファイルにまとめる準備を始め、それが終了すると[ダウンロード]ボタンが表示されるので、ボタンをクリックしてダウンロードする。
インポートする(=読み込む)ときには、ダッシュボードの[プロジェクトの作成]ボタンのクリックで表示される[プロジェクトの作成]画面の[Import Project]ボタンをクリックする。すると[プロジェクトのインポート]が表示されるので(図2-4-B)、プロジェクト名と説明を入力し、[インポート方法]の[プロジェクトのパッケージをアップロード]チェックボックスをクリックして選択する。そして[ファイルを選択]ボタンをクリックして保管しておいたZIPファイルを指定してアップロードする。ZIPファイルが問題なくIDEに読み込まれると、ダッシュボードにそのプロジェクトが表示される。
“初めてのOnsen UIアプリ”のビルド
ひと息ついたら、いよいよ“初めてのOnsen UIアプリ”のビルドだ。ビルドとはAndroidならAndroidの、iOSならiOSのアプリケーションファイルを作成することをいう。
Monacaアプリではこれを、Monaca IDEの[ビルド]メニューで行う。今回はアップルやグーグルに支払う費用が発生しないという理由で、Androidアプリとしてのデバッグビルドを行う。デバッグビルドとはテスト用アプリのビルドをいい、Androidでは無料でデバッグビルドが行える。
[Androidアプリ設定]
Androidアプリのデバッグビルドは今のままでも実行できるが、IDEメニューの[設定]-[Androidアプリ設定]では、アプリケーション情報の記述や、アプリアイコン、アプリの起動時に表示されるスプラッシュ画面のファイルをアップロードして指定することもできる。
図2-5はその例で、[アプリケーション名]のフィールドでは、自動的に入力される“初めてのOnsen UIアプリ”を短くして“初めてのアプリ”としている。[アプリケーション名]はデバイスのドロワー(アプリ一覧表示画面)などで使用される。名前が長いと表示が途中で切れることになるので、できるだけ短い方がよい。
[パッケージ名]は、アプリをマーケットで公開するときには世界中のAndroidアプリと区別する名前になるので、重複を確実に避けるため、通常は作成者のドメインを逆にした逆ドメインの形式で記述する(例:jp.himco.firstApp)。
[Androidアプリ設定]ではまた、アプリのアイコンやスプラッシュ画面の画像をアップロードして指定できる。図2-6ではテスト用に、[96 x 96]のアイコンファイルと[xhdpi]用のスプラッシュファイルをアップロードしている。その他の設定はデフォルトのまま変更していない。設定が終わったら[保存する]ボタンをクリックする。
Androidアプリのビルドは、IDEメニューの[ビルド]-[Androidアプリのビルド]から行う。図2-7に示す[Androidアプリのビルド]が表示されるので、今の場合には[デバッグビルド]を選択して[次へ]をクリックする。するとMonaca IDEがビルド作業に入る。しばらく待って“おめでとうございます!”というメッセージが表示されたらデバッグは成功だ。これでAndroidのアプリケーションファイル(拡張子は.apk)がMonacaのサーバー上に作成されたことになる。
ネットワークインストール
AndroidのMonacaデバッガーには、ネットワークインストールという非常に便利な機能が組み込まれている。これを使用するには、デバッガーのプロジェクト一覧画面に表示されているプロジェクト名の右にある[i]ボタンをタップする。するとそのプロジェクトの情報が表示されるので、雲(=クラウド)アイコンの[インストール]ボタンをタップする(図2-8)。ネットワークインストールの続行を確認するダイアログが表示されるので[Yes]をタップし、インストールを許可すると、デバッガーがMonacaサーバーからアプリケーションファイルをダウンロードしてインストールする。
インストールが成功すると、デバイスのドロワーに、デバッグビルドしたアプリのアイコンが現れる(図2-9)。これをタップして起動すると、通常のアプリ同様、スプラッシュ画面が表示された後、アプリの最初の画面が表示される。これはデバッグビルドしたアプリではあるものの、他のネイティブアプリと同じAndroidアプリだ。
【コラム】[ローカルPCにダウンロード]してからデバイスにインストールする方法
■
今回は“初めてのOnsen UIアプリ”のファイルの中身を調べ、それをAngularJS流に書き換えた。そしてそのアプリをデバッグビルドし、デバイスに実際にインストールした。HTMLとJavaScriptのコードをAngularJS流に書き換えるときには、angular.module('myApp', ['onsen'])
というコードを記述して、“生の”AngularJSに少しだけ触れたが、次回はこのAngularJSに真正面から取り組んでいくのでお楽しみに。
更新履歴
- 2014/11/28
- MonacaのBasicプランの提供サービスの変更に伴い、「プロジェクトの削除とアーカイブへの移動」の章を削除し、新たに「プロジェクトのエクスポートとインポート」の章を追加しました。
※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
1. Onsen UI+AngularJSで効率的にモバイルアプリが作れるMonaca
HTML+CSS+JavaScriptを使ってスマホやタブレットで動作するアプリが簡単に作成できる「Monaca」を基礎から解説する入門者向け連載(改訂版)がスタート。今回はMonaca/Onsen UI/AngularJSの概要とMonaca IDE、Monacaデバッガーを紹介。
2. 【現在、表示中】≫ Monacaで作る、初めてのOnsen UIアプリ
新規作成した“初めてのOnsen UIアプリ”プロジェクトの各ファイルをAngularJS流に書き換える。そのアプリをデバッグビルドし、デバイスに実際にインストールする。
3. Onsen UIの舞台裏で働くAngularJSの世界
AngularJS流のデータ/コントローラー/表示の実装方法と、AngularJSのディレクティブによるHTML要素の操作方法、データの追加、AngularJS機能のサービスについて解説する。
4. AngularJSの方法でMonacaアプリを作ってみよう(前編)
実践的なMonacaアプリ開発の一例として、オープンデータのWebサービスを使ったアプリの作成方法を説明する。Monacaアプリ開発実践編の第1弾。