user3700786 user3700786 - 7 months ago 14
Javascript Question

ng-model changes all select at once

jsfiddle

Hi.

I have a problem with my application. I have to write several selects by using ng-repeat and each of these selects must be filled with the same data.

The problem is, when the one is changed, others selects are changes to the same value - why?.

I suppose that the problem is in the ng-model - maybe I don't understand how the "hierarchy" of the ng-model works.


  • If the name of the ng-model is only "option" - it doesn't work!

  • If the name of the ng-model is "something.option" - it also doesn't
    work!

  • If the name of the ng-model is "something.else.option" - it does work
    but all selects are filled!



HTML:

<div ng-controller="MyCtrl">
<div ng-if="models" ng-repeat="m in models">
<br><label>{{m.model}} ({{m.no}})</label><br>

<select ng-model="models.m.opModel" ng-options="opt.value as opt.text for opt in options" ng-change="foo()"></select>
</div>
</div>


JS:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
$scope.models = [
{'no':'A', 'model':'alpha'},
{'no':'B', 'model':'beta'},
{'no':'C', 'model':'gamma'}
];
$scope.options = [
{'value':1, 'text':'one'},
{'value':2, 'text':'two'},
{'value':3, 'text':'three'}
];

$scope.foo = function(){
alert($scope.models.m.opModel);
}
}


What am I doing wrong?

Thanks a lot.

Answer

You've created a scope object called "m" which is the current child of the "models" list. So for each dropdown, you're going to have a different "m" scope object. This is what you need to bind to in your ng-model so that the dropdown is bound to it's unique parent in the "models" list.

Change <select ng-model="models.m.opModel"> to <select ng-model="m.opModel" to fix the problem.

To access the value with the foo() function, you'll need to use this updated function:

 $scope.foo = function(index){
   alert($scope.models[index].opModel)
 }

And update the <select> like this:

<select ng-model="m.opModel" ng-options="opt.value as opt.text for opt in options" ng-change="foo($index)"></select>

You're creating an ng-model called "opModel" in the ng-repeat which means you'll have three new opModels under $scope.models. This is an array you can access later using an index value to specify which of the $scope.models[].opModel you want to access.

Notice that I've changed the ng-change code to send the current $index which is basically an ng-repeat counter. So your foo() function will receive either a 0, 1 or 2 which lets us access the specific ngModel that we need to access.