Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

ng-repeat要素でさまざまな繰り返しを表現するには?(ng-repeat)

2015年11月16日

ng-repeatディレクティブの応用的な使い方として、「重複した値を含んだ配列」「ハッシュ(連想配列)」「複数の要素セット」の内容を順に処理して出力する方法を説明。

  • このエントリーをはてなブックマークに追加

 別稿「TIPS:配列の内容を順に出力するには?」でも紹介したように、ng-repeatディレクティブを利用することで、配列の内容を順に取り出し、いわゆるループ処理(=繰り返し処理)を実装できます。本稿では、ng-repeatディレクティブを利用して、以下のような繰り返し処理を行う方法を紹介します。

  • 重複した値を含んだ配列を出力する
  • ハッシュ(連想配列)の内容を順に出力する
  • 複数の要素のセットを繰り返し出力する

重複した値を含んだ配列を出力する

 例えば、以下のコードはごく単純なng-repeatディレクティブの例に見えますが、エラーとなります。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<ul>
  <li ng-repeat="d in data">{{d}}</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyController', ['$scope', function($scope) {
    $scope.data = [ 'AngularJS', 'JavaScript', 'EcmaScript', 'AngularJS' ];
  }]);
</script>
</body>
</html>
ng-repeatディレクティブの典型的なエラー例(track.html)
ng-repeatディレクティブで発生したエラー

 これは、ng-repeatディレクティブが内部的には、繰り返し項目の増減を、配列要素をキーに管理しているためです。このため、同じ値(ここでは「AngularJS」が重複)に対しては、キーの重複エラーを返すわけです。

 これを避けるには、ng-repeatディレクティブに対して、トラッキング式を追加します。トラッキング式とは、繰り返し項目を追跡するためのキーを決める式で、以下のように指定します。

HTML
<li ng-repeat="d in data track by $index">{{d}}</li>
トラッキング式を明示したコード(track.html)
正しく配列の内容をリスト表示できる
正しく配列の内容をリスト表示できる

 トラッキング式は、繰り返し式の末尾にtrack by句で指定します。つまり上記のコードは、配列のインデックス番号($index)で繰り返し項目を追跡しなさい、という意味になります。インデックス番号は重複しませんので、今度は正しくサンプルが動作し、配列の内容をリスト表示できます。

ハッシュ(連想配列)の内容を順に出力する

 配列だけでなく、ハッシュの内容を順に出力することもできます。例えば以下は、単一の記事オブジェクトを、ng-repeatディレクティブを使って出力する例です。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
</head>
<body ng-controller="MyController">
<ul>
  <li ng-repeat="(key, value) in article">
    {{key}}:{{value}}
  </li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyController', ['$scope', function($scope) {
    $scope.article = {
      url: 'https://www.buildinsider.net/web/angularjstips',
      title: 'AngularJS TIPS',
      author: '山田祥寛',
      released: new Date(2015, 7, 10)
    };
  }]);
</script>
</body>
</html>
ハッシュの内容をリスト表示するコード(hash.html)
記事情報をテーブル表示
記事情報をテーブル表示

 ハッシュを繰り返し処理する際には、キー(プロパティ名)と値を受け取る仮変数が必要となります。この例であれば、変数key(キー)、value(値)です。

複数の要素のセットを繰り返し出力する

 ng-repeatディレクティブは、デフォルトで、現在の要素(開始タグ~閉じタグ)を配列要素の数だけ繰り返し処理します。そのため、例えば<dt><dd>のように複数の要素を繰り返し出力するようなことは、そのままではできません。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<dl>
  <dt ng-repeat="article in articles">{{article.title}}</dt>
  <dd>{{article.url}}/ ({{article.released | date: 'yyyy年MM月dd日'}})</dd>
</dl>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="i18n/angular-locale_ja-jp.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyController', ['$scope', function($scope) {
    $scope.articles = [
      {
        url: 'https://www.buildinsider.net/web/jqueryref',
        title: 'jQuery逆引きリファレンス',
        author: 'WINGSプロジェクト',
        released: new Date(2015, 8, 1)
      },
      ……中略……
    ];
  }]);
</script>
</body>
</html>
複数の要素セットを繰り返し出力するためのコード(失敗例。set.html)

サンプル全体はこちらからダウンロード・実行できる。

HTML
<dl>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    jQuery逆引きリファレンス
  </dt>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    AngularJS TIPS
  </dt>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    jQuery Mobile逆引きリファレンス
  </dt>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    実例に学ぶチーム開発におけるNuGet導入のすすめ
  </dt>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    Objective-CユーザーのためのSwift入門
  </dt>
  <dt ng-repeat="article in articles" class="ng-binding ng-scope">
    業務Webアプリエンジニアのための「Bootstrap」入門
  </dt>
  <dd class="ng-binding">/ ()</dd>
</dl>
実行結果のHTMLソースを見ると、<dt>要素だけが繰り返しの対象になっている(開発者ツールから確認)

 この例では、<dt>要素だけが繰り返しの対象になっていることが確認できます。これを<dt><dd>ともに繰り返しの対象にするには、(ng-repeatの代わりに)ng-repeat-startng-repeat-end属性を利用します。上の例であれば、以下のように書き換えます。

HTML
<dl>
  <dt ng-repeat-start="article in articles">{{article.title}}</dt>
  <dd ng-repeat-end>{{article.url}} ({{article.released | date: 'yyyy年MM月dd日'}})</dd>
</dl>
複数の要素セットを繰り返し出力するためのコード(成功例。set.html)
HTML
<dl>
  <dt ng-repeat-start="article in articles" class="ng-binding ng-scope">
    jQuery逆引きリファレンス
  </dt>
  <dd ng-repeat-end="" class="ng-binding ng-scope">
    https://www.buildinsider.net/web/jqueryref (2015年09月01日)
  </dd>
  <dt ng-repeat-start="article in articles" class="ng-binding ng-scope">
    AngularJS TIPS
  </dt>
  <dd ng-repeat-end="" class="ng-binding ng-scope">
    https://www.buildinsider.net/web/angularjstips (2015年08月10日)
  </dd>
  ……中略……
  <dt ng-repeat-start="article in articles" class="ng-binding ng-scope">
    業務Webアプリエンジニアのための「Bootstrap」入門
  </dt>
  <dd ng-repeat-end="" class="ng-binding ng-scope">
    http://codezine.jp/article/corner/528 (2015年01月05日)
  </dd>
</dl>
実行結果のHTMLソースを見ると、<dt>/<dd>ともに繰り返しの対象(開発者ツールから確認)

 今度は、<dt><dd>要素の範囲で繰り返し処理が実行されていることが確認できます。

処理対象:コレクション カテゴリ:基本
処理対象:繰り返し処理 カテゴリ:基本
処理対象:ディレクティブ(Directive) カテゴリ:基本
API:ng-repeat(ngRepeat) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)

※以下では、本稿の前後を合わせて5回分(第31回~第35回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
31. 交互に異なるスタイルクラスを適用するには?(ng-class-odd/ng-class-even)

ng-class-even/ng-class-oddディレクティブを使って、表の行などの繰り返しデータの偶数行もしくは奇数行に対し、スタイルを設定・変更する方法を説明する。

AngularJS TIPS
32. 配列の内容を順に出力するには?(ng-repeat)

配列の内容を順に処理して出力できるng-repeatディレクティブの基本的な使い方を説明する。

AngularJS TIPS
33. 【現在、表示中】≫ ng-repeat要素でさまざまな繰り返しを表現するには?(ng-repeat)

ng-repeatディレクティブの応用的な使い方として、「重複した値を含んだ配列」「ハッシュ(連想配列)」「複数の要素セット」の内容を順に処理して出力する方法を説明。

AngularJS TIPS
34. ログをコンソールに出力するには?($log)

AngularJSで開発者ツールのコンソールにログを出力する方法を説明。また、ログの種類や、デバッグログの表示/非表示の切り替え方法も紹介する。

AngularJS TIPS
35. サーバーサイドと非同期通信するには?($http)

AngularJSでサーバーサイドのWeb APIと非同期通信する方法を説明。また、ログの種類や、ショートカットメソッドについても紹介する。

サイトからのお知らせ

Twitterでつぶやこう!