two way binding not working with ng-repeat
Asked Answered
R

4

7

I have a simple ng-repeat list, in which i am assigning current list item value to another property on the controller as follows:

  <li ng-repeat="num in list">
    <input type="text" ng-init="value = num" ng-model="value" />
    <button type="button" class="btn btn-primary" ng-click="save()">Save</button>
  </li>

But when i click the Save button i get default value set for $scope.value. I expect the value for the particular input text to be displayed.

Here is the controller:

 angular.module('myApp', [])
    .controller('MyController', function($scope){
      $scope.value = false;
      $scope.list = [0, 1, 2, 3, 4];
      
      $scope.save = function() {
         alert($scope.value);
      }
    });

How can i access the updated value of a input item in my controller on save function call.

Here is the plunker for the same: plnkr

Update: I am expecting the value to be fetched to controller without passing it as a parameter.

Roland answered 25/3, 2015 at 16:42 Comment(6)
ngRepeat creates its own scope.Wormwood
Okay, so how to retrieve the value.Roland
You can pass value to save function, like ng-click="save(value)" accept the parameter and then perform your operationWormwood
I can do that, but that defies the two way binding purpose.Roland
then use ng-model="$parent.value" Wormwood
your plunkeris not updatedAuxesis
O
10

Wow I can't believe most people have missed this. If you are using Angular 1.2 then you should definitely check out track by keyword in your ngRepeat directive.

<li ng-repeat="num in list track by $index">
    <input type="text" ng-model="list[$index]" />
    <button type="button" class="btn btn-primary" ng-click="save()">Save</button>
</li>

Bottom line is stay away from primitive types when binding since it will give you sync issues.

Fellas please put more time and effort into researching your solutions instead of just posting for points.

Hope this helps!

Ossetia answered 16/5, 2015 at 22:9 Comment(0)
G
3

ngRepeat create a scope, so, object is passed by reference and number by value. Your code is problematic, if you successfully update the value, it will update all the numbers in ng-repeat. You can do this:

html

    {{value.val}} <!-- for check the value -->
<li ng-repeat="num in list">
    <input type="text" ng-model="num" />
    <button type="button" class="btn btn-primary" ng-click="value.val=num">Save</button>
  </li>

javascript

angular.module('myApp', [])
    .controller('MyController', function($scope){
      $scope.value = {val:false};
      $scope.list = [0,1,2,3,4];
});

http://jsfiddle.net/oq6zdeLd/

I'm sorry about my english...

Gibran answered 25/3, 2015 at 17:23 Comment(0)
P
0

here it is how you can do that

<li ng-repeat="num in list">
    <input type="text" ng-init="value = num" ng-model="value" />
    <button type="button" class="btn btn-primary" ng-click="save(value)">Save</button>
  </li>


angular.module('myApp', [])
    .controller('MyController', function($scope){
      $scope.value = false;
      $scope.list = [0, 1, 2, 3, 4];

      $scope.save = function(argument) {
         $scope.value = argument;
         alert($scope.value);
      }
    });
Prefabricate answered 25/3, 2015 at 16:48 Comment(3)
I am expecting the value to be fetched to controller without passing in a parameter actually.Roland
according to me this is not Idea behind data binding.A controller's job with respect to Angular is to set up functions and properties that the view can use.please refer this linkPrefabricate
@Roland In this case you dont have to pass value as argument. 'angular.module('myApp', []) .controller('MyController', function($scope){ $scope.value = false; $scope.list = [0, 1, 2, 3, 4]; $scope.getValue = function(){ $scope.ValuetoSave= $scope.value; } $scope.save = function() { alert($scope.ValuetoSave); } $scope.$watch('$scope.value', $scope.computeNeeded); });Prefabricate
A
0

Lets not abuse the expression "2 way binding" ;)

Your controller has one scope and there is just one $scope.value in that scope. You cannot force is to have multiple values simultaneously.

ng-repeat creates new scope for each li. And even if you try to use $parent.value, your controller's $scope.value will only have the last assigned value in ng-init

You best bet in this case to pass the value as an argument. Hope this helped to explain the issue a little more. Correct me if I am wrong.

Afterguard answered 25/3, 2015 at 17:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.