ngRepeat

概要

ngRepeatディレクティブは、コレクションから各項目のテンプレートをインスタンス化します。 各テンプレートのインスタンスは、現在のコレクション項目が設定されたループの変数と、  項目のインデックスまたはキーが設定された$indexが与えられた、自身のスコープを取得します。

各テンプレートのインスタンスのローカルスコープで、下記の特別な変数が使用可能になります。

変数 説明
$index

型:number

現在、繰り返し処理中の何番目なのかを示します。(0..length-1)

$first

型:boolean

現在、要素の繰り返し処理中の最初であれば、trueになります。

$middle

型:boolean

現在、要素の繰り返し処理中の中間(最初と最後で無い)であれば、trueになります。

$last

型:boolean

現在、要素の繰り返し処理中の最後であれば、trueになります。

$even

型:boolean

$indexが偶数であればtrue、そうでなければfalseです。

$odd

型:boolean

$indexが奇数であればtrue、そうでなければfalseです。

特別な開始点と終了点の繰り返し

親要素に代わり、ひと続きの要素を繰り返し処理するために、ngRepeat(もしくは同等のngディレクティブ)は、 最初と最後のポイントをng-repeat-startng-repeat-endを使用してそれぞれ明確に定義することで、 リピーターの範囲拡張をサポートします。 ng-repeat-startディレクティブは、ng-repeatと同様に動作しますが、 ng-repeat-endが設定されたHTMLタグまでを含む、全てのHTMLコード(定義されたタグを含む)を繰り返し処理します。

下記は、この機能を使用した例です。

<header ng-repeat-start="item in items">
  Header {{ item }}
</header>
<div class="body">
  Body {{ item }}
</div>
<footer ng-repeat-end>
  Footer {{ item }}
</footer>

上記の例のitemsの変数に['A','B']が入力されていると、 出力は下記は次のようになります。

<header>
  Header A
</header>
<div class="body">
  Body A
</div>
<footer>
  Footer A
</footer>
<header>
  Header B
</header>
<div class="body">
  Body B
</div>
<footer>
  Footer B
</footer>

ngRepeatの開始と終了のカスタマイズも、AngularJSから提供される全てのHTMLディレクティブ構文をサポートします。 (data-ng-repeat-start、x-ng-repeat-start、ng:repeat-start など)

使用方法

<要素 ng-repeat="{repeat_expression}">
   ...
</要素>

ディレクティブ情報

  • このディレクティブは、新しいスコープを作成します。
  • このディレクティブは、優先度レベル1000で実行されます。

アニメーション

enter
新しい項目がリストに追加された、またはフィルター適用後に項目が現れた際にトリガされます。
leave
項目がリストから削除された、またはフィルター適用後に項目から隠された際にトリガされます。
move
隣接する項目がフィルターで除外されて再整列が発生した、または項目の内容が再整列された際にトリガされます。

Click here to learn more about the steps involved in the animation.

引数

ngRepeat 説明
ngRepeat

型:繰り返し式

コレクションをどのような方法で列挙するかの式を指定します。 現在、下記のフォーマットがサポートされています。

変数 in 式

変数はユーザーが定義するループ変数であり、 式は、与えられたコレクションを列挙するためのスコープ式です。

例: album in artist.albums

(キー, 値) in 式

キーと値はユーザーが定義し、 式は、与えられたコレクションを列挙するためのスコープ式です。

例: (name, age) in {'tarou':10, 'hanako':12}

変数 in 式 track by トラッキング式

任意のトラッキング関数を提供することもでき、 これを使用することでコレクション内のオブジェクトをDOM要素に結び付けることが可能です。 もし、トラッキング関数が指定されなければ、ng-repeatはコレクション内で識別されてている要素を、 結び付ける対象とします。 トラッキング関数が同一のキーから複数の結果を得るとエラーになります。 (これは、同じDOM要素に2つの異なるオブジェクトをマッピングする事が出来ないことを意味します。) トラッキング式が指定される前に、フィルターは式に適用されるべきです。

例: item in itemsは、`item in items track by $id(item)'として評価されており、 DOM要素が配列内のitemのIDに暗黙的に結び付けられていることを意味します。

例: item in items track by $id(item)
組み込みの$id()関数は、一意の$$hashKeyプロパティを配列内の各項目に割り当てるのに使用することが可能です。 その次に、このプロパティはID識別によって、配列内の対応する項目に関連付けられているDOM要素へのキーとして使用されます。 配列内のオブジェクトを移動すると、DOM内の要素も同様に移動されます。

例: item in items track by item.id は、データベースから項目を取得する際の典型的なパターンです。 この場合、オブジェクトのidは重要ではありません。 idが同じである限り、2つのオブジェクトは等価であるとみなされます。

例: item in items | filter:searchText track by item.id
項目に対して、フィルターの適用とトラッキング式を組み合わせて使用することが出来ます。

デモ

この例では、名前のリストのためにスコープを初期化し(ng-init="friends = ...)、ngRepeatが各個人を表示するのに使用します。

<!doctype html>
<html ng-app="ngAnimate">
  <head>
    <link rel="stylesheet" type="text/css" href="animation.css">
    <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script>
    <script src="http://code.angularjs.org/1.2.3/angular-animate.min.js"></script>
  </head>
  <body>
    <div ng-init="friends = [
      {name:'John', age:25, gender:'boy'},
      {name:'Jessie', age:30, gender:'girl'},
      {name:'Johanna', age:28, gender:'girl'},
      {name:'Joy', age:15, gender:'girl'},
      {name:'Mary', age:28, gender:'girl'},
      {name:'Peter', age:95, gender:'boy'},
      {name:'Sebastian', age:50, gender:'boy'},
      {name:'Erika', age:27, gender:'girl'},
      {name:'Patrick', age:40, gender:'boy'},
      {name:'Samantha', age:60, gender:'girl'}
    ]">
      I have {{friends.length}} friends. They are:
      <input type="search" ng-model="q" placeholder="filter friends..." />
      <ul class="example-animate-container">
        <li class="animate-repeat" ng-repeat="friend in friends | filter:q">
          [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
        </li>
      </ul>
    </div>
  </body>
</html>
.example-animate-container {
  background:white;
  border:1px solid black;
  list-style:none;
  margin:0;
  padding:0 10px;
}

.animate-repeat {
  line-height:40px;
  list-style:none;
  box-sizing:border-box;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  -webkit-transition:all linear 0.5s;
  transition:all linear 0.5s;
}

.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}

.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:40px;
}
it('should render initial data set', function() {
  var r = using('.doc-example-live').repeater('ul li');
  expect(r.count()).toBe(10);
  expect(r.row(0)).toEqual(["1","John","25"]);
  expect(r.row(1)).toEqual(["2","Jessie","30"]);
  expect(r.row(9)).toEqual(["10","Samantha","60"]);
  expect(binding('friends.length')).toBe("10");
});

it('should update repeater when filter predicate changes', function() {
  var r = using('.doc-example-live').repeater('ul li');
  expect(r.count()).toBe(10);

  input('q').enter('ma');

  expect(r.count()).toBe(2);
  expect(r.row(0)).toEqual(["1","Mary","28"]);
  expect(r.row(1)).toEqual(["2","Samantha","60"]);
});
<!doctype html>
<html ng-app="ngAnimate">
  <head>
<style type="text/css">.example-animate-container {
  background:white;
  border:1px solid black;
  list-style:none;
  margin:0;
  padding:0 10px;
}

.animate-repeat {
  line-height:40px;
  list-style:none;
  box-sizing:border-box;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  -webkit-transition:all linear 0.5s;
  transition:all linear 0.5s;
}

.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}

.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:40px;
}
</style>
    <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script>
    <script src="http://code.angularjs.org/1.2.3/angular-animate.min.js"></script>
  </head>
  <body>
    <div ng-init="friends = [
      {name:'John', age:25, gender:'boy'},
      {name:'Jessie', age:30, gender:'girl'},
      {name:'Johanna', age:28, gender:'girl'},
      {name:'Joy', age:15, gender:'girl'},
      {name:'Mary', age:28, gender:'girl'},
      {name:'Peter', age:95, gender:'boy'},
      {name:'Sebastian', age:50, gender:'boy'},
      {name:'Erika', age:27, gender:'girl'},
      {name:'Patrick', age:40, gender:'boy'},
      {name:'Samantha', age:60, gender:'girl'}
    ]">
      I have {{friends.length}} friends. They are:
      <input type="search" ng-model="q" placeholder="filter friends..." />
      <ul class="example-animate-container">
        <li class="animate-repeat" ng-repeat="friend in friends | filter:q">
          [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
        </li>
      </ul>
    </div>
  </body>
</html>

 Back to top

© 2017 Google
Licensed under the Creative Commons Attribution License 3.0.

このページは、ページトップのリンク先のAngularJS公式ドキュメント内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • AngularJSの更新頻度が高いため、元のコンテンツと比べてドキュメントの情報が古くなっている可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。