1

How bind ng-model to element inside ng-repeat? In fact i want to bind object in array to element and when type in input element create new input element with new ng-model. while in this example all ng-model are same.

var myApp = angular.module('app', []);
myApp.controller("MyCtrl",function($scope){
   $scope.items = [];
    $scope.item = {
        phone:""
    };
    $scope.items.push($scope.item);

    $scope.addItem = function(index){
        if($scope.items[index+1] == null)
          $scope.items.push($scope.item);
        console.log($scope.items);
    }
    
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
   <div ng-repeat="line in items track by $index">
      <!-- typing here should auto update it's preview above -->
      <input ng-model="line.phone" ng-keydown="addItem($index)"/>
      <!-- many other fields here that will also affect the preview -->
    </div>
</div>
Hadi J
  • 16,989
  • 4
  • 36
  • 62

3 Answers3

2

I think you want this one. Note that I use

$scope.items.push(angular.copy($scope.item))

to make a copy of object. Without this you always put reference to same object in array, so changing one of them causes others to be changed as well.

var myApp = angular.module('app', []);
myApp.controller("MyCtrl",function($scope){
   $scope.items = [];
    $scope.item = {
        phone:""
    };
    $scope.items.push(angular.copy($scope.item));

    $scope.addItem = function(index){
        if($scope.items[index+1] == null)
          $scope.items.push(angular.copy($scope.item));
        console.log($scope.items);
    }
    
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
   <div ng-repeat="line in items track by $index">
      <!-- typing here should auto update it's preview above -->
      <input ng-model="line.phone" ng-keydown="addItem($index)"/>
      <!-- many other fields here that will also affect the preview -->
    </div>
</div>
Dmitry Pavliv
  • 35,333
  • 13
  • 79
  • 80
  • how remove value when added new element? – Hadi J Jul 28 '15 at 07:19
  • @hadi, I think this was descried in another [_tread_](http://stackoverflow.com/questions/15453979/how-do-i-delete-an-item-or-object-from-an-array-using-ng-click) - it has perfect explanation. Just add `ng-click="remove(line)"` and add `remove` behaviour in your controller – Dmitry Pavliv Jul 28 '15 at 07:24
  • when type in second input element it added new input element with first input element value. while i don't want this. – Hadi J Jul 28 '15 at 07:27
  • change also first occurrence of `$scope.items.push($scope.item);` with `$scope.items.push(angular.copy($scope.item));`. See updated answer for details – Dmitry Pavliv Jul 28 '15 at 07:29
  • thanks. its work correctly but in console appear this error: Error: [ngModel:nonassign] http://errors.angularjs.org/1.3.14/ngModel/nonassign? – Hadi J Jul 28 '15 at 07:37
  • there is no error for me, are you sure it comes from exactly this code? – Dmitry Pavliv Jul 28 '15 at 07:39
1

If you pass like $scope.items.push($scope.item); then $scope.item is reference to the same object and it will push to the array multiple times, because objects are referenced types, if you push primitive data types it will act differently,

define the item local in the function,

$scope.addItem = function(index){
        if($scope.items[index+1] == null) {
            var item = {
                 phone:""
            };
        }
        $scope.items.push(item );
        console.log($scope.items);
  }

var myApp = angular.module('app', []);
myApp.controller("MyCtrl",function($scope){
    $scope.items = [];
    var item = {
                 phone:""
    };
    $scope.items.push(item);

     $scope.addItem = function(index){
        if($scope.items[index+1] == null) {
            var item = {
                 phone:""
            };
            $scope.items.push(item );
            console.log($scope.items);
        }            
      }
    
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
   <div ng-repeat="line in items track by $index">
      <!-- typing here should auto update it's preview above -->
      <input ng-model="line.phone" ng-keydown="addItem($index)"/>
      <!-- many other fields here that will also affect the preview -->
    </div>
</div>
Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92
1

You can also use the key as array key of the model

<div ng-repeat="(key, line) in items track by $index">
  <input ng-model="line.phone[key]" ng-keydown="addItem($index)"/>
</div>
michelem
  • 14,430
  • 5
  • 50
  • 66
  • you forget to mention what it actually does: `
    {{items|json}}
    ` - I don't think this is what OP wants
    – Dmitry Pavliv Jul 28 '15 at 07:21
  • OP should declare phone as an array. Like `$scope.item = { phone: [] };` then your above code will work perfectly :-) – Vineet Jul 28 '15 at 07:22