The `ngRepeat` directive instantiates a template once per item from a collection. Each template
instance gets its own scope, where the given loop variable is set to the current collection item,
and `$index` is set to the item index or key.
Special properties are exposed on the local scope of each template instance, including:
| Variable  | Type            | Details                                                                     |
|-----------|-----------------|-----------------------------------------------------------------------------|
| `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |
| `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |
| `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |
| `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |
| `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |
| `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |
<div class="alert alert-info">
  Creating aliases for these properties is possible with `ngInit`.
  This may be useful when, for instance, nesting ngRepeats.
</div>
# Iterating over object properties
It is possible to get `ngRepeat` to iterate over the properties of an object using the following
syntax:
```js
<div ng-repeat="(key, value) in myObj"> ... </div>
```
You need to be aware that the JavaScript specification does not define the order of keys
returned for an object. (To mitigate this in Angular 1.3 the `ngRepeat` directive
used to sort the keys alphabetically.)
Version 1.4 removed the alphabetic sorting. We now rely on the order returned by the browser
when running `for key in myObj`. It seems that browsers generally follow the strategy of providing
keys in the order in which they were defined, although there are exceptions when keys are deleted
and reinstated. See the [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
If this is not desired, the recommended workaround is to convert your object into an array
that is sorted into the order that you prefer before providing it to `ngRepeat`.  You could
do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
or implement a `$watch` on the object yourself.
# Tracking and Duplicates
`ngRepeat` uses $watchCollection to detect changes in
the collection. When a change happens, ngRepeat then makes the corresponding changes to the DOM:
* When an item is added, a new instance of the template is added to the DOM.
* When an item is removed, its template instance is removed from the DOM.
* When items are reordered, their respective templates are reordered in the DOM.
To minimize creation of DOM elements, `ngRepeat` uses a function
to "keep track" of all items in the collection and their corresponding DOM elements.
For example, if an item is added to the collection, ngRepeat will know that all other items
already have DOM elements, and will not re-render them.
The default tracking function (which tracks items by their identity) does not allow
duplicate items in arrays. This is because when there are duplicates, it is not possible
to maintain a one-to-one mapping between collection items and DOM elements.
If you do need to repeat duplicate items, you can substitute the default tracking behavior
with your own using the `track by` expression.
For example, you may track items by the index of each item in the collection, using the
special scope property `$index`:
```html
   <div ng-repeat="n in [42, 42, 43, 43] track by $index">
     {{n}}
   </div>
```
You may also use arbitrary expressions in `track by`, including references to custom functions
on the scope:
```html
   <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
     {{n}}
   </div>
```
<div class="alert alert-success">
If you are working with objects that have an identifier property, you should track
by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
will not have to rebuild the DOM elements for items it has already rendered, even if the
JavaScript objects in the collection have been substituted for new ones. For large collections,
this signifincantly improves rendering performance. If you don't have a unique identifier,
`track by $index` can also provide a performance boost.
</div>
```html
   <div ng-repeat="model in collection track by model.id">
     {{model.name}}
   </div>
```
When no `track by` expression is provided, it is equivalent to tracking by the built-in
`$id` function, which tracks items by their identity:
```html
   <div ng-repeat="obj in collection track by $id(obj)">
     {{obj.prop}}
   </div>
```
<div class="alert alert-warning">
**Note:** `track by` must always be the last expression:
</div>
```
<div ng-repeat="model in collection | orderBy: 'id' as filtered_result track by model.id">
    {{model.name}}
</div>
```
# Special repeat start and end points
To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)
up to and including the ending HTML tag where **ng-repeat-end** is placed.
The example below makes use of this feature:
```html
  <header ng-repeat-start="item in items">
    Header {{ item }}
  </header>
  <div class="body">
    Body {{ item }}
  </div>
  <footer ng-repeat-end>
    Footer {{ item }}
  </footer>
```
And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:
```html
  <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>
```
The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such
as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).