What are the differences between ng-repeat and ng-options and why do they not behave the same way?

ng-repeat creates a new scope for each iteration so will not perform as well as ng-options.

For small lists, it will not matter, but larger lists should use ng-options. Apart from that, It provides lot of flexibility in specifying iterator and offers performance benefits over ng-repeat.


From the documentation:

Note: ngOptions provides an iterator facility for the element which should be used instead of ngRepeat when you want the select model to be bound to a non-string value. This is because an option element can only be bound to string values at present.

This fiddle makes the point more clear: select2 will bind to select 1 but not the other way around. Click the buttons and the reason will reveal itself :-)

HTML

<div ng-app ng-controller="MyCtrl">
  <select ng-model="selectedPerson" >
    <option ng-repeat="obj in people" value="{{obj.id}}">
      {{obj.name}}
    </option>
  </select>
  <select ng-model="selectedPerson" 
    ng-options="p.id as p.name for p in people">
  </select>
  selected: {{selectedPerson}} {{typeofSelectedPerson()}}
    <button ng-click="selectedPerson=2">Jao</button>
    <button ng-click="selectedPerson='1'">Ze</button>
</div>

JS

function MyCtrl($scope){
    $scope.selectedPerson = 1;
    $scope.people = [
        {
            id: 1,
            name: 'Ze'
        },
        {
            id: 2,
            name: 'Jao'
        }
    ];

    $scope.typeofSelectedPerson = function(){
        return typeof $scope.selectedPerson;
    }
}

In many cases, ngRepeat can be used on elements instead of ngOptions to achieve a similar result. However, ngOptions provides some benefits, such as more flexibility in how the 's model is assigned via the select as part of the comprehension expression, and additionally in reducing memory and increasing speed by not creating a new scope for each repeated instance.


ng-options is the directive which is designed specifically to populate the items of a dropdown list. One major advantage using ng-options for the dropdown is, it allows us to pass the selected value to be an object. Whereas, using ng-repeat the selected value can only be string.

<select ng-model="selectedPerson" >
      <option ng-repeat="obj in people" value="{{obj.id}}">{{obj.name}}</option>
</select>
<h1> Id of the selected item is : {{selectedPerson}}</h1>

By Using the above method, the value of the selectedPerson is always a string.

<select ng-model="selectedPerson" ng-options='obj.name for obj in people'></select>
 <h1> Id of the selected item is : {{selectedPerson.id}}</h1>
 <h1> Name of the selected item is : {{selectedPerson.name}}</h1>

Here, the value of the selected person is an object so we can print any required field of the object by passing the complete object.


ng-repeat give problem while send information back to controller because in general we show name to the user but use ID/Index of the option for backend operations.

Simple words- with ng-options you may use complete JavaScript object.

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="selectedName" ng-options="x.name for x in names">
</select>
<!--It will display complete object-->
{{selectedName}}
<!--It will display object's age-->
{{selectedName.age}}
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = [{"name":"Neeraj","age":"21"},    {"name":"John","age":"22"},     {"name":"David","age":"23"}];
});
</script>

</body>
</html>

but with ng-repeat you have to deals with string.

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">

<select ng-model="selectedName">
<option ng-repeat="x in names">{{x.name}}</option>
</select>
<!--It will display only selected name not complete object-->
{{selectedName}}
<!--It won't work-->
{{selectedName.age}}
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = [{"name":"Neeraj","age":"21"},{"name":"John","age":"22"},{"name":"David","age":"23"}];
});
</script>

<p>This example shows how to fill a dropdown list using the ng-repeat    directive.</p>

</body>
</html>