How to update ng-repeat values in angular js?

26,165

Solution 1

The easiest way is to use angular.copy to create a clone of the object when edit is clicked and then when save is clicked copy the data to the item in the array.

First initilize $scope.editedItem

$scope.editedItem = {};

For editrow we store the currently edited index in $index and then clone the data into $scope.editedItem.

$scope.editrow = function($index){
    $scope.istrue = true;
    $scope.$index = $index;
    angular.copy($scope.items[$index], $scope.editedItem);
}

Then in save we clone the data back into the object in the array:

$scope.save = function(){
    $scope.istrue = false;
    angular.copy($scope.editedItem, $scope.items[$scope.$index]) 
}

The view needs to be updated to instead use editedItem:

<div class="editpopup editpopup-{{istrue}} ">
    <p>edit id:<input type="text" ng-model="editedItem.id"></p>
    <p>edit pname:<input type="text" ng-model="editedItem.pname"></p>
    <button ng-click="save()">save</button>
    <button ng-click="closepopup()">cancel</button>
 </div>

JsFiddle

Solution 2

I had this same issue. here was my fix


My original code that didn't update the object

<div class="info" ng-repeat="email in vm.contactData.emails.other">
      <input type="text" ng-model="email" />
</div> 

Used the items $index to properly bind it

<div class="info" ng-repeat="email in vm.contactData.emails.other">
      <input type="text" ng-model="vm.contactData.emails.other[$index]" />
</div> 

This binding creates a re-draw issue because it doesn't know if the updated item in the array is referencing the same item that was in that spot before. To fix this i had to make a slight change to formatting of the array.

['[email protected]','[email protected]']

becomes

[
   {'email': '[email protected]'},
   {'email': '[email protected]'}
]

and

<div class="info" ng-repeat="email in vm.contactData.emails.other">
     <input type="text" ng-model="vm.contactData.emails.other[$index]" />
</div> 

becomes

<div class="info" ng-repeat="email in vm.contactData.emails.other">
      <input type="text" ng-model="vm.contactData.emails.other[$index].email" />
</div> 

after these changes you should have a proper bind without any re-draw issues where the input field loses focus.

Share:
26,165
Pioter
Author by

Pioter

Updated on July 05, 2022

Comments

  • Pioter
    Pioter about 2 years

    I am new to angular js, I have an array I am looping it through ng-repeat directive, and I have written code for copy, remove, and edit values in the array.

    If I want to remove or copy I can do it, done? But if I click on edit one popup box will appear there I want to edit the values those updated values should update in the array.

    How can I get it done?

    <!doctype html>
    <html>
    <head>
     <title>Angular app</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js">
      </script>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <style type="text/css">
      .listv{
         margin-bottom: 30px;
      }
      .editpopup{
         width: 250px;
         height: 250px;
         border: 1px solid black;
         display: none;
         position: absolute;
         top: 0px;
         left: 0px;
         bottom: 0px;
         right: 0px;
    
         background-color:gray;
      }
      .editpopup-true{
         display: block;
      }
      .editpopup-false{
         display: none;
      }
      </style>
    </head>
     <body ng-app="myApp">
        <div ng-controller="myCon">
         <div ng-repeat="s in items" class="listv">
            <span>{{s.id}}</span>
            <span>{{s.pname}}</span>
            <button ng-click="removeStudent($index)">remove</button>
            <button ng-click="copyrow($index)">copy</button>
            <button ng-click="editrow($index)">edit</button>
         </div></br>
    
         <div class="editpopup editpopup-{{istrue}} ">
            <p>edit id:<input type="text" ng-model="editedid"></p>
            <p>edit pname:<input type="text" ng-model="editedname"></p>
            <button ng-click="save($index)">save</button>
            <button ng-click="closepopup()">cancel</button>
         </div>
    
      </div>            
    

          var myApp=angular.module('myApp',[]);
          myApp.controller('myCon',function($scope){
          $scope.items=[{id:1,pname:'box1'},{id:2,pname:'box2'}, {id:3,pname:'box3'}];
    
        $scope.removeStudent=function($index){
          $scope.items.splice($index,1);
        }
      $scope.copyrow=function($index){
    
         $scope.len=$scope.items.length;
         $scope.ids=$scope.items[$index].id;
         $scope.pnames=$scope.items[$index].pname
    
         $scope.items.push({
              id:$scope.len+1,
              pname:$scope.pnames 
          });
      }
      $scope.editrow=function($index){
         $scope.istrue=true;
         $scope.editedid=$scope.items[$index].id;
         $scope.editedname=$scope.items[$index].pname;
      }
      $scope.closepopup=function(){
         $scope.istrue=false;
    
      }
      $scope.save=function($index){
         $scope.istrue=false;
         $scope.s.name=$scope.editedname;
      }
     });
    

    here is jsfiddle

  • Mohammad Kermani
    Mohammad Kermani almost 8 years
    It worked well for me, Is there any other possible way? Or maybe in Angular2? Thank you