I've found some great answers on how to get the value of an ng-model
inside an ng-repeat
, but so far, I haven't found any that cover the setter. Suppose I have something like this:
<div ng-repeat="item in getItems()">
<input ng-model="itemTitle" ng-model-options={getterSetter:true}">
</div>
If I had a single input box, I'd use something like this:
...
var _val = '';
$scope.itemTitle = function(val){
return angular.isDefined(val) ? (_val = val) : _val;
}
...
However, that would change the value for every single input box. Is it possible to define the variables and a setter, potentially using arrays? Or is there a better method to get and set input boxes inside an ng-repeat?
The ngModel directive is a directive that is used to bind the values of the HTML controls (input, select, and textarea) or any custom form controls, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during form validations.
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.
The controller creates a child scope and the ng-repeat , which will create an LI element for each item in the list of To Do items. It also creates a new scope for each element.
AngularJS ng-repeat Directive The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.
The answer by Wayne Ellery does answer the question as it shows "a better method to get and set input boxes inside an ng-repeat".
However if you actually want to use ng-model-options="{getterSetter: true}"
within an ng-repeat
as is implied in the question and the comments then it's a little more complicated as within your getterSetter
function you don't know which item from the ng-repeat
is being referred to.
Essentially what you need to do is pass a different getter/setter function for each item, and you can do that by passing a function to ng-model
that creates your row specific getter/setter for you.
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat='row in items'>
<span>{{row.name}}</span>
<input type='text' ng-model='createTitleGetterSetter(row.name)'
ng-model-options='{ getterSetter: true }' />
</div>
<hr/>
<pre>{{ itemTitles | json }}</pre>
</div>
And the JS code:
var app = angular.module('app',[]);
app.controller('ctrl', function($scope) {
$scope.items = [
{'name': 'a'},
{'name': 'b'},
{'name': 'c'}
];
$scope.itemTitles = {};
$scope.createTitleGetterSetter = function(name) {
if (!$scope.itemTitles[name]) {
$scope.itemTitles[name] = {
getterSetter: function(newValue) {
return arguments.length === 0 ?
$scope.itemTitles[name].title :
$scope.itemTitles[name].title = newValue;
},
title: ''
}
}
return $scope.itemTitles[name].getterSetter;
};
});
JSFiddle here: http://jsfiddle.net/zLg3mLd0/1/
In this case the item titles are of course not stored along with the item objects (if you wanted to do that, just a simple ng-model
would suffice) but in the itemTitles
map.
Credit to this answer and its comments on which this answer is heavily based.
You would set ng-model
to item.title
so each object in the array returned from getItems()
would contain a title
.
<div ng-repeat="item in getItems()">
<input type="text" ng-model="item.title"/>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With