LoginSignup
6
6

More than 5 years have passed since last update.

monacaでスマホアプリを作ろう #5

Posted at

Serviceを使ってみる

MVCのV(html),C(Controller)に続き、Mの役割を担うServiceを使ってみます。
Model関連の処理をService内にカプセル化することにより、バックエンドをMySQLだろうがOracleだろうがGoogle Cloud Endpointsだろうが、他のレイヤーに影響を与えず自由自在に切り替えらえるわけです。
実際にはバックエンドを切り替えることはほぼ無い(ですよね?)ので、 ここでは実践的な例として、まずモックアップ用のデータを扱うサービスを作ってみます。

js/service/osservice.jsを作成
service_create.png

中身

osservice.js

app.factory('OSService', function () {
    var service = {};

    var oss= [
        {"name":"KiKat", "kind":"android", "desc":"androidos4.4系です"},
        {"name":"JellyBean", "kind":"android", "desc":"androidos4.1-3系です"},
        {"name":"Honycomb", "kind":"android","desc":"androidos3.x系です"},
        {"name":"Mavericks", "kind":"osx","desc":"Mac 10.9"},
        {"name":"Mountain Lion", "kind":"osx", "desc":"Mac 10.8"},
        {"name":"Lion", "kind":"osx","desc":"Mac 10.7"},
        {"name":"SnowLeopard", "kind":"osx", "desc":"Mac 10.6"},
    ];

    /**
     * OSのリストを取得する
     * この関数内で遅延が発生しても良いようにcallbackで返す
     */
    service.getOSList= function(callback) {
            callback(oss);
    }

    // serviceオブジェクトを返す
    return service;
});

js/controller/page1controller.js を修正

page1controller.js

app.controller('Page1Ctrl',function($scope, OSService){ // OSServiceをインジェクト

    /**
     * 検索結果を受け取るコールバック関数
     */
    var searchCallback = function(data){
        $scope.oss = data;
    };

    OSService.getOSList(searchCallback);

}) ;

index.htmlにosservice.jsの読み込みを追加

index.html
       .
       .
    <link rel="stylesheet" href="css/style.css">
    <script src="js/controller/page1controller.js"></script>
    <script src="js/service/osservice.js"></script> <!-- 追加 -->
    <script>
        var app = ons.bootstrap();
       .
       .

どうでしょうか。プレビューするとまったく変わらない結果が表示されるはずです。

ポイントは、Controller側でOSServiceを使用するためにインジェクトしている箇所と、検索の遅延を考慮して検索結果をコールバック関数経由でControllerに返しているところです。javascriptぽいですね。

本当に遅延に対応しているのかよ?ということで、遅延するようコードを修正

osservice.js
       .
       .
   service.getOSList= function(callback) {
            setTimeout(function(){callback(oss)},3000); //3秒待って結果を返す
    }
       .
       .

どうでしょう?プレビューしたら表示されましたか?されませんね。 :cry:
AngularJSに$scope.ossが更新されたことを通知する必要があるようです。

というわけでpage1controller.jsを修正

page1controller.js
       .
       .
    var searchCallback = function(data){
        $scope.oss = data;
        $scope.$apply();  // VIEWを更新する
    };
       .
       .

これで3秒後にOSの一覧が表示されるはずです。

さらにpage1.htmlを修正して読み込み待ちを表示してみます。

page1.html
<ons-page>
<div ng-controller="Page1Ctrl">
  <ons-toolbar>
    <div class="center">List With Header</div>
  </ons-toolbar>

<div ng-if="!!oss">
  <!-- ossが無い場合は表示しない-->
  <ons-list>
    <ons-list-header>Android Versions</ons-list-header>
    <ons-list-item modifier="chevron" ng-repeat="os in oss" ng-if="os.kind == 'android'">
    {{os.name}}
    </ons-list-item>

    <ons-list-header>MacOSX Versions</ons-list-header>
    <ons-list-item modifier="chevron" ng-repeat="os in oss" ng-if="os.kind == 'osx'">
    {{os.name}}
    </ons-list-item>
  </ons-list>
</div>
<div ng-if="!oss" style="text-align:center;">
  <!-- ossが無い場合に読み込み待ちを表示 -->
      <br>
      <br>
      <ons-icon icon="spinner" spin="true"></ons-icon>
</div>
</div>
</ons-page>

angularjsの機能であるng-ifを使ってossが無い場合の表示を制御しています。
これでまた一歩アプリっぽくなってきました!

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6