【Phonegap/Cordova + Onsen UI 04】ng-repeatを使用してリストデータを表示する

 

はじめに。ng-repeatについて

みなさん、こんにちは!

今回は、OnsenUIの便利機能である、 ng-repeatを使っていきましょう。
ng-repeatは、配列をバインドすると、配列の要素分、指定要素を描画してくれるというとても便利なものです。

前回までで作っていた住所検索アプリで保存機能を実装し、その保存しておいたデータを照会する時に、このng-repeatで保存したデータを全件描画する、という感じで実装に組み込んでいきましょう。

(前回の記事はこちら⇒【Phonegap/Cordova + Onsen UI 03】住所検索アプリをOnsenUI+Angular.jsに書き換える)

その前に、ng-repeatについてもう少し詳しく説明しておきます。

<ons-list>
<ons-list-item ng-repeat="item in items" ng-click="processItemSelect($index)">
{{item.myName}}
</ons-list-item>
</ons-list>

使い方は上記のような感じです。
例えば、リストとして要素を列挙する場合なら、ons-listのons-list-itemにng-repeatを付与します。
list-itemを繰り返し表示して欲しいので。
ここで、ng-repeatには、(配列から取り出した1要素の変数名) in (バインドする配列名) の形式で属性値を与えます。
バインドする配列名は、もちろんAngularのコントローラスコープ内に存在する配列を与えます。

とある行が選択された時のイベントをハンドルしたい場合は(例えばタップやクリックイベントなら)、ng-clickにコントローラを与えます。
何番目の要素のイベントかを拾いたい場合には、$indexを使用します。
ng-repeatディレクティブを使用した場合に、$indexという変数を使用することができますので、それをコントローラに引数として渡せばokです。

他にも、色々機能がありますが、とりあえずこれだけ覚えておけば大丈夫です。

前回ソースを修正する

それでは、前回までのアプリに、データ保存と保存データのリスト表示機能を付与していきます。

index.html

まずはHTMLの方を修正します。

<!DOCTYPE html>
<html>

  <!-- ----------------------------------------

    住所検索のためのAPIは、zipcloud さんのAPIを使用しています
    URL: http://zipcloud.ibsnet.co.jp/

  ---------------------------------------- -->

  <head>
  <meta charset="utf-8" />
  <meta name="format-detection" content="telephone=no" />
  <meta name="msapplication-tap-highlight" content="no" />
  <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
  <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

    <link rel="stylesheet" href="lib/onsen/css/onsenui.css" />
    <link rel="stylesheet" href="lib/onsen/css/onsen-css-components-blue-basic-theme.css" />

    <script src="lib/onsen/js/angular/angular.js"></script>
    <script src="lib/onsen/js/onsenui.js"></script>

    <script src="jquery/jquery-1.11.3.min.js"></script>

    <script src="js/mainController.js"></script>
    <script src="js/searchAddress.js"></script>

  <style>
   ons-page{
    font-family: "ヒラギノ角ゴシック Pro", "Hiragino Kaku Gothic Pro", 'メイリオ' , Meiryo , Osaka, "MS Pゴシック", "MS PGothic", sans-serif !important;
   }
   #input_zipno{
    width: 100%;
    height: 48px;
    font-size: 42px;
    margin-top: 4px;
    margin-bottom: 4px;
   }
   .delete-button{
    background-color: rgb(240, 80, 80);
   }
   .op-buttons ons-button{
    width: 100%;
    text-align: center;
   }
   .result{
    font-size: 32px;
   }
   .result > p{
    margin: 4px;
   }
  </style>

  <script type="text/javascript" src="cordova.js"></script>
  <script type="text/javascript" src="js/searchAddress.js"></script>
  <script type="text/javascript" src="js/storageManager.js"></script>

  <title>郵便番号検索</title>

  </head>
  <body>
    <ons-page ng-controller="MainController">

      <ons-toolbar>
        <div class="center">住所検索</div>
      </ons-toolbar>

      <ons-row>
        <input id="input_zipno" type="text" ng-model="zipno" />
      </ons-row>

      <ons-row>
        <ons-button modifier="large" ng-click="searchAddress()"><ons-icon icon="search"></ons-icon>search</ons-button>
      </ons-row>

      <ons-row class="op-buttons">
        <ons-col>
          <ons-button modifier="light" ng-click="showSavedData()">show saved data</ons-button>
        </ons-col>
        <ons-col>
          <ons-button modifier="light" ng-click="saveData()">save data</ons-button>
        </ons-col>
        <ons-col>
          <ons-button class="delete-button" ng-click="deleteAll()">delete all</ons-button>
        </ons-col>
      </ons-row>

      <ons-row>
        <h3>検索結果</h3>
      </ons-row>
      <ons-row>
        <ons-col>
          {{got_zipno}}
        </ons-col>
        <ons-col>
          {{got_address}}
        </ons-col>
      </ons-row>

      <ons-list>
        <ons-list-header>保存した住所</ons-list-header>
        <ons-list-item ng-repeat="item in savedItems">
          {{item.zip_no}}:{{item.zip_address}}
        </ons-list-item>
      </ons-list>

    </ons-page>


  </body>
</html>

79~87行目は、Bootstrap+jQueryの時にあった検索結果の保存&照会&削除用のボタンです。
削除はともかく、照会と保存ボタンは必須なので、置いておきます。
後に記事として書く予定ですが、ons-row, ons-colは、レイアウトを行うために配置しています。

101~106行目は、今回の目玉、ons-listとng-repeatを記述している部分です。
今回はとりあえず表示だけ行う予定ですので、ons-list要素にはng-repeatのみでng-clickは付与していません。
コントローラスコープで、savedItemsという配列を宣言しますので、その配列をバインドし、1要素をitemとして参照可能にします。
104行目が、リストの1要素であるitemのプロパティにアクセスしています。

mainController.js

次は、コントローラ側を少し修正します。

{
  'use strict';
  var module = ons.bootstrap("ONSEN_01_APP", ['onsen']);

  var smanager;

  module.controller("MainController", function ($scope, $http) {

    smanager  = new storageManager("ZIP_ADDRESS_DATA");

  	$scope.zipno = "";
    $scope.got_zipno = "";
    $scope.got_address = "";

    // 保存した住所情報リスト表示用
    $scope.savedItems = [];

    // 住所検索を行う
    $scope.searchAddress = function(){

      var zip_no = $scope.zipno;

      // 入力チェック
      if(zip_no &amp;amp;&amp;amp; (zip_no.match(/[0-9]{7}/) != null)) {

        var params = {};
        params["zipcode"] = zip_no;
        params["callback"] = "JSON_CALLBACK";

        // angularのhttpサービスでjsonp
        $http.jsonp(
          "http://zipcloud.ibsnet.co.jp/api/search",
          {
            params: params
          }
        ).success(function(data){
          // successコールバック
          if(!data.results){
            alert("情報が見つかりませんでした...");
            return;
          }

          var address_info = data.results[0];

          $scope.got_zipno = address_info.zipcode;
          $scope.got_address = address_info.address1 + " " + address_info.address2 + " " + address_info.address3;

        }).error(function(){
          alert("エラーが発生しました");
        });

      }
      else{
        alert("7桁の数字を入力してください");
      }
    }

    // 保存されたデータの照会
    $scope.showSavedData = function(){
      $scope.savedItems = [];

      var data = smanager.getAll();
      for(var p in data){
        $scope.savedItems.push({zip_no: p, zip_address: data[p]});
      }
    }

    // データの保存
    $scope.saveData = function(){
      if($scope.got_zipno == ""){
        alert("保存するデータがありません");
        return;
      }

      smanager.set($scope.got_zipno, $scope.got_address);
      alert("保存しました");
    }

    // 全件削除
    $scope.deleteAll = function(){
      smanager.deleteAll();
      alert("削除しました");
    }

  });


}

58~83行目が、今回追加した保存した住所情報の操作に関するメソッドです。
今回は、画面に表示されるshow saved dataボタンを押下すると、リストに現在保存されている情報が表示されるようにしました。
63~65行目で、保存されていたデータを画面に表示するための配列に追加しています。
HTML側で、item.zip_noとitem.addressというプロパティで照会することにしているので、それに合わせたプロパティ名にしておきます。

わずかこれだけで、保存したデータを画面にリスト表示してくれるようになります!なんと便利な!!

動作確認

実際に実機で動作確認を行うと下記のようになります。

Screenshot_2016-08-16-01-50-32

住所検索⇒保存
を何度か繰り返した後に、show saved dataボタンを押下すると、保存したデータが一覧リストとして表示されることが確認できると思います。

結構アプリっぽい見た目になってきましたね!!

今回は以上です!

次回記事はこちら⇒【Phonegap/Cordova + Onsen UI 05】ナビゲーションでページ遷移!再帰的キーワードサジェストアプリを作る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です