2

Why is my external template not rendering items using ng-repeat ?

--- AngularJS 1.1.5

I stumbled on this bug but I'm not sure if it's the same issue? If it is are there any work arounds?

Here's a Plunker using a static list but the solution needs to support two way binding because the data is dynamic. ( That's how it's supposed to work anyway... )

controller

.controller('main', ['$scope',function($scope) {
  $scope.items = ['a','b','c'];
}])

directive

.directive('items', function() {
    return {
        restrict: 'E',
        replace: true,
        controller: 'main',
        templateUrl: 'items.html',
        link: function(scope, controller) {
        }
    };
})

items.html

<div ng-repeat="item in items">
    {{item}}
</div>

3 Answers 3

3

This is because your directive uses a template that does not have on root element, try:

<div>
  <h1>What?</h1>
  <div ng-repeat="item in items">
    {{item}}
  </div>
</div>

for the template.

EDIT: To understand this, we can have a look at the source of angular itself. The compile-Methods responsible for this can be looked at here. The culprit is the mergeTemplateAttributes and the need for one root becomes apparent when looking at the intent here: When replacing DOM nodes, angular needs to pass on the attributes. When there is more than one node in the template fetched it will throw an error, as it cannot decide on the node which the original attributes will be applied to (see here for the error thrown).

The quote the developers here:

When the element is replaced with HTML template then the new on the template need to be merged with the existing attributes in the DOM. The desired effect is to have both of the attributes present.

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

2 Comments

+1 Thankyou that was it. I wonder why you "need" to wrap with a root element.
I extended my answer a bit on the topic.
3

Update your items.html as below:

 <div>
  <h1>What?</h1>
  <div ng-repeat="item in items">
      {{item}}
  </div>
</div>

Comments

1

You need to wrap the template with one root like this:

<div>
    <h1>What?</h1>
    <div ng-repeat="item in items">
        {{item}}
    </div>
</div>

Comments

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.