2018年6月14日木曜日

MONACAサンプルアプリの導入と、ソースコードの解読1

今回は、MONACAを用いてアプリケーションの開発を試みるのだが、一から作成するといった作業は時間的に余裕がありそうにないので、あらかじめ用意されているテンプレートの編集を行い、アプリケーションの開発を試みる。
まず、MONACA Docsに接続し、サンプルアプリをクリックする。すると、サンプルアプリケーション一覧が表示される。今回作成したいアプリケーションはグラフの描画機能を持っているものなので、「チャートアプリ」の導入を行った。

図1 サンプルアプリ一覧
導入を行う際は、上記図1のアプリ図に示されている「Direct Import」をクリックする事で、MONACAにインポートすることができる。また、インポートを行う際は、下記の図2のような確認ダイアログが表示される。
図2 サンプルアプリインポートダイアログ
インポートを行い、MONACAのダッシュボードに移動すると、下記図3の様に無事にインポートされていることが分かる。尚、MONACAは無料試遊版だとプロジェクトを3つまでしか保有することが出来ないため、注意が必要である。
図3 MONACAダッシュボード
仕様の確認を行うため、スマートフォン版でアプリケーションの確認を行ったのだが、
下記図4のようなポップアップが表示された。
図4 MONACAアプリケーション図1
これは,アンプルアプリのCordovaのバージョンが古いため、表示された警告メッセージである。そこで、一旦ブラウザ版の方に戻り、「onsen World Poplation」を「クラウドIDEで開く」で編集画面に遷移する。そして、設定タブから「Cordova プラグインの管理」をクリックする。
図5 クラウドIDE図1
すると、上記図5のような画面が表示される。どうやら最新バージョン「7.1.0」に対してこちらのバージョンは「6.5.0」であったため、エラーが表示されたようである。「7.1.0にアップグレード」をクリックすると、下記図6のような画面が表示され、
図6 クラウドIDE図2
OKをクリックする事で、図7のような画面が表示され、無事にアップデートを行う事ができた。
図7 クラウドIDE図3
無事にアップデートを行う事が出来たので、次はスマートフォンでアプリケーションの大まかな仕様について確認を行った。
図8 MONACAアプリケーション図2
まずアプリケーションを実行すると、上記図8の様な画面が表示された。
これは各国毎にデータを分けて格納されていることが分かる。
今回は「Japan」のサンプルデータの確認を行ってみた。
図9 MONACAアプリケーション図3
「Japan」をタップすると、上記図9のような図が表示された。とあるデータを参照し、この様なグラフの描画を行っているのだろう。また青色のタブをタップすることで、図10の様な年別でのデータ表示の切り替えも行えることが出来る。
図10 MONACAアプリケーション図4
これでおおよその仕様の確認を行う事が出来た。次にこのアプリケーションのソースコードの解読を行い、どのデータを書き換えれば、我々が作成したいアプリケーションの開発が行えるかどうかを試みる。
このアプリケーションを形成しているものは主に「index.html」,「index.js」,「countries.json」の3つである。また、今回は実際に解読を行った部分のみを抜粋して記載している。

#index.html

<body>
 <ons-navigator page="main.html" var="navi"></ons-navigator>

 <ons-template id="main.html">
  <ons-page ng-controller="CountriesController as countries">
   <ons-toolbar>
    <div class="center">World Population</div>
   </ons-toolbar>

   <div class="filter-input-container">
    <input class="search-input" ng-model="query" placeholder="Filter countries" type="search" value="" />
   </div>
   <ons-list>
    <ons-list-item modifier="chevron" ng-click="countries.showCountry(country)" ng-repeat="country in countries.list | filter:query">
     {{ country }}
    </ons-list-item>
   </ons-list>
  </ons-page>
 </ons-template>

 <ons-template id="country.html">
  <ons-page ng-controller="CountryController as country">
   <ons-toolbar>
    <div class="left">
     <ons-back-button>Back</ons-back-button>
    </div>
    <div class="center">
     {{ country.name }}
    </div>
   </ons-toolbar>

   <ons-list class="year-select-container">
    <ons-list-item>
     <select class="text-input text-input--transparent" ng-model="country.year" ng-options="year for year in country.years" style="margin-top: 4px; width: 100%;">
     </select>
    </ons-list-item>
   </ons-list>

   <population-chart data="country.population" ng-if="country.showChart"></population-chart>
  </ons-page>
 </ons-template>
</body>
1行目の<body></body>の間にあるHTMLがアプリが表示する画面(View)を定義している。2行目~40行目にかけて多く見られる<ons-…>の「ons」は「Onsen-UI」というモバイルアプリの開発に特化したUIコンポーネントである。<ons-page>で囲まれたページの中に、他のHTML要素やOnsen UIコンポーネントを記述してユーザインターフェースを開発する。
<ons-navigator…>は、Onsen UIのサイトの記載によると、ページの切り替え機能を提供するコンポーネントだとわかる。
<ons-template…>は、これもOnsen UIのサイトの記載によると、id属性に指定した名前をpageのURLとしてons-navigatorなどのコンポーネントから参照できるHTMLを定義するものである。これを使うと個々の画面のHTMLファイルを別々に分けなくとも1つのファイル内に記述できるようになる。
この機能を使って、4行目~20行目、22行目~40行目の<ons-template…></ons-template>はそれぞれで独立したページの指定を行っている。
4行目~20行目は「main.html」のファイル、22行目~40行目は「country.html」のファイルを指定している。
15行目にある「…ng-repeat="country in countries.list…」は、AngularJSのCountriesController(国名を管理するコントローラ)からcountry(国名)のデータを繰り返し取得し、16行目の{{ country }}によって、アプリ画面に国名が表示されるようにしている。

#index.js

angular.module('app', ['onsen'])
.controller('CountriesController', ['$scope', 'Countries', function($scope, Countries) {
  var that = this;
  Countries.get()
    .then(
      function(countries) {
        that.list = countries;
      }
    );
  this.showCountry = function(country) {
    $scope.navi.pushPage('country.html', {data: {name: country}});
  };
}])
.service('Countries', ['$http', function($http) {
  this.get = function() {
    return $http.get('countries.json')
      .then(
        function(response) {
          return response.data.countries;
        }
      );
  };
}])
.service('Population', ['$http', function($http) {
  this.get = function(country, year) {
    return $http.jsonp('http://api.population.io:80/1.0/population/' + year + '/' + country + '/?format=jsonp&callback=JSON_CALLBACK')
      .then(
        function(response) {
          return response.data;
        }
      );
  };
}])
MonacaはAngulaJSというJavaScriptのフレームワークを用いている。1行目はAngulaJSのモジュールを定義しているところである。モジュールはAngularJSの最も基本的な単位で、アプリを構成する様々な部品(コントローラ、サービス、ディレクティブなど)をモジュールの下に作成していく。
2行目は「CountriesController」という名前のコントローラメソッドの記述である。$scopeというのは、 ビュー(アプリの画面のこと:すなわちHTML5で作成する画面)にデータなどを渡したり、ビューから発生したイベントを監視するなど、ビューとのやり取りを行うことができる特別なオブジェクトである。具体的には、このコントローラが参照されるHTMLノード(この場合はmain.htmlのons-pageノード)自身を表している。
3行目では、$scopeを意味するthisを一時変数thatに代入している(いろいろな問題を回避するため、$scopeを使わずthisを利用するようになっているらしい)。
4行目~9行目はサービスCountries(14~23行目)からデータ(国名一覧:countries.json)の取得を行い、うまくいった場合は自身のリストにデータを流し込むといった処理を行っている。
10行目~12行目は、引数に指定されたcountryの詳細ページを表示すべく、country.htmlへの画面遷移を行うメソッドを定義している。this.showCountryのようにthisで修飾することで、このコントローラのスコープ内で利用できるメソッドを定義できる。
14行目~22行目は、JSON形式の国名一覧「countires.jon」からデータを取得するサービスメソッドCountriesの定義である。このサービスはCountriesControllerのサービスとしてコントローラに注入されて利用されている(2行目)。
24行~33行は、「Population」というサービスメソッドの定義である。引数に指定した国及び年(それぞれcountryおよびyear)の人口データを取得すべく、26行目で
http://api.population.io:80/1.0/population/' + year + '/' + country + '/?format=jsonp&callback=JSON_CALLBACK
というURLを作成し、Webサービスを提供するサーバに人口データの要求を行っている。
ここで、試しに2018年の日本の人口データをブラウザから要求してみた。手作業で作成したURLは次のとおりである。
http://api.population.io/1.0/population/2018/Japan?format=jsonp
すると、以下の様なJSON形式の人口データが返ってくることを確認できた。
[
  {
    "females": 493727,
    "country": "Japan",
    "age": 0,
    "males": 520667,
    "year": 2018,
    "total": 1014404
  }
今回解読したソースコードをおおまかに整理すると、以下の図11のようになる。
図11 index.jsフロー図
まず、controller「CountryController」に注入したservice「Countries」のgetメソッドを使ってcountries.jsonから国名データを取得する。その後、取得したデータをcontrollerのlist属性に流しこむといった具合だ。
今回はサンプルアプリの導入と、簡単なプログラムの分析を行った。次回は解析しきれていないソースコードを分析し、目的のスマホアプリを開発するにはどの部分の書き換えを行うべきかを見定めていきたい。


0 件のコメント:

コメントを投稿

レーダーチャートの表示2

前回 レーダーチャートの表示を行うことが出来たので、今回は実際の値を代入したグラフの描画を試みる。 .controller('RaderChartController', ['$scope', 'Countries', funct...