0

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,

2
  • 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". Commented Feb 15, 2014 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 Commented Feb 15, 2014 at 18:44

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

2 Comments

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.
Thanks, @ElieRoux. If you like my answer, please mark it as the correct answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.