Changing Objects Inside Angular Area Inside ng-repeat

I am creating a form in HTML using ng-repeat to create form elements from an object in an area. I also use this object to create other elements outside of ng-repeat.

A simplified example looks like this in HTML:

<div ng-app="App"> <div ng-controller="Ctrl"> <div class="block1"> <form ng-repeat="(key, value) in test"> <label>{{key}}</label> <input ng-model="value" /> <p>{{value}}</p> </form> </div> <div class="block2"> <p> {{test.a}} </p> <p> {{test.b}} </p> </div> </div> </div> 

and this is in JS:

 angular.module('App', []); function Ctrl($scope) { $scope.test = { a:"abc", b:"def" } } 

In this example, the text in block 2 is set to the initial values test.a and test.b Input values ​​and <p> values ​​inside the loop are also set to the initial value.

When I change the values ​​inside the inputs, the <p> values ​​inside the ng-repeat block are updated correctly, but the <p> tags in block 2 are not updated.

Why is this behavior? Does ng-repeat create its own isolated area? If so, how can I get the controller level area for updating? Also, can anyone explain the thinking behind this behavior and any of its benefits?

JSFiddle mapping problem

+6
source share
2 answers

ng-repeat creates a child region for each repeating element. As a result, you are trying to pass the primitive to a child region that will not create a reference to the parent. However, when you pass objects, you pass the original reference to the object.

From the mouth of one of the Angular fathers:

Always have a point in the ng model

This is a great Angular Best Practices video by Angular creator (2012/12/11). Go to minute 31 to explain this exact situation well.

Change data to an array of objects:

 $scope.test = [{ val:"abc",key:'a'}, {val:"def",key:'b'} ] 

Then in the repeater:

 <form ng-repeat="item in test"> <label>{{item.key}}</label> <input ng-model="item.val" /> <p>{{item.val}}</p> </form> 

Demo

+22
source

try the following:

  angular.module('App', []); function Ctrl($scope) { $scope.test = [ {label:"a", value:"abc"}, {label:"b", value:"def"} ] } 

and

 <div ng-app="App"> <div ng-controller="Ctrl"> <div class="block1"> <form ng-repeat="o in test"> <label>{{o.label}}</label> <input ng-model="o.value" /> <p>{{o.value}}</p> </form> </div> <div class="block2"> <p> {{test[0].value}} </p> <p> {{test[1].value}} </p> </div> </div> </div> 

Angularjs exploits the fact that objects are passed by reference. So, if you pass an object to a function and change the object inside the function, the external object also changes. Look at this updated JSFiddle.

+2
source

All Articles