Naughty.Coder
Naughty.Coder

Reputation: 3960

Ng-Repeat and creating new child scopes

I'm just trying to understand
if np-repeat creates a new child scope in each iteration, then why this code sets the variable in the parent scope and not in the child scope:

var app = angular.module('myApp', []);

        app.controller('WorldCtrl', function($scope) {
            $scope.population = 7000;
            $scope.countries = [
                {name: 'France', population: 63.1},
                {name: 'United Kingdom', population: 61.8},
            ];
        });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myApp' ng-controller='WorldCtrl'>
<li ng-repeat="country in countries">
        <span ng-init="country.name='Egypt'"></span>
        {{country.name}} has population of {{country.population}}
</li>
  
 <hr>
    World's population: {{population}} millions {{countries}}
</div>

Expected output:

 Egypt has population of 63.1
 Egypt has population of 61.8
World's population: 7000 millions [{"name":"France","population":63.1},{"name":"United Kingdom","population":61.8}]

Upvotes: 0

Views: 119

Answers (2)

Explosion Pills
Explosion Pills

Reputation: 191729

ng-repeat does indeed create its own scope which overshadows variables defined in the parent scope. That is to say if the parent scope had a property called country, you would not be able to access it in the ng-repeat template.

However, the country property that is created in the child scope is made of references to properties in the parent scope. This is how JavaScript prototypal inheritance works.

You could get around this by overwriting the entire country property instead of using the prototype chain.

var app = angular.module('myApp', []);

        app.controller('WorldCtrl', function($scope) {
            $scope.population = 7000;
            $scope.countries = [
                {name: 'France', population: 63.1},
                {name: 'United Kingdom', population: 61.8},
            ];
        });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myApp' ng-controller='WorldCtrl'>
<li ng-repeat="country in countries">
        <span ng-init="country = {name: 'Egypt', population: country.population}"></span>
        {{country.name}} has population of {{country.population}}
</li>
  
 <hr>
    World's population: {{population}} millions {{countries}}
</div>

Upvotes: 1

tommybananas
tommybananas

Reputation: 5736

The answer is because as an object, you are passing references and not copies of the model. The ng-repeat is creating a variable country which is a reference of the current iteration object of the array countries, and so you are altering the property of a referenced object, not a copy.

Upvotes: 1

Related Questions