I have an item tree in $scope on which I want to iterate with ng-repeat and include a different template according to node type. The tree is something like

$scope.item = {
  ID: 1,
  children: {
    1: {
      ID: 11,
      },
    2: {
      ID: 12,
    }
  },
};

The problem is that when I do something like

<div ng-repeat="item in item.children">
  item.ID : {{item.ID}}
  <div ng-include="showVars(item.ID)"></div>
</div>

the argument of the showVars function is the item.ID value as evaluated in the parent scope, not the subscope created by ng-repeat. When displayed with {{item.ID}}, the value is correct though.

Example in this Fiddle.

My understanding is that the value in the subscope is not updated yet when I call the function, am I right? Is this AngularJS' normal behaviour or a bug?

Edit:

To make it more explicit, in the Fiddle I expect

calling getTemplate with $scope.item.ID = 12 and itemID = 12

instead of

calling getTemplate with $scope.item.ID = 1  and itemID = 12

because ng-repeat is supposed to assign $scope.item with the variable.

Thank you,

share|improve this question
    
I don't understand what the problem is. all the logs show that the correct item ID is received by the method: "and itemID = 12". And the included template also displays the child ID: "My Template with item.ID = 12". – JB Nizet Feb 15 '14 at 18:24
    
Sorry, I should have been more explicit : the problem is, as you can see in the log, that, when ng-include is evaluated, $scope.item is still the same as in parent scope, while I would expect it to be the $scope.item of child scope created by ng-repeat. To make it even more explicit, I would expect calling getTemplate with $scope.item.ID = 12 and itemID = 12 instead of calling getTemplate with $scope.item.ID = 1 and itemID = 12 – Elie Roux Feb 15 '14 at 18:44
up vote 4 down vote accepted

This is expected behavior.

When you created the controller's showVars function, you are closing over $scope, which is the scope of the parent controller. So when you reference $scope, you are getting that scope that was injected into the controller.

In other words, $scope doesn't change based on the execution of the function. This is why you want to pass the item into the function as a parameter.

If you want access to the child scope in the function, you can do this using this:

this.item.ID

Here is a working JS Fiddle

share|improve this answer
1  
Thank you very much, this is a great help to me! I globally understand now, especially with the help of this answer and this doc. – Elie Roux Feb 15 '14 at 20:54
    
Thanks, @ElieRoux. If you like my answer, please mark it as the correct answer. – Brian Genisio Feb 16 '14 at 2:03
    
Done! Thank you! – Elie Roux Feb 16 '14 at 9:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.