Summary
To see the problem in Internet Explorer and the solution, check out this Code Pen. By replacing
<div>{{item.name}}</div>
with <div> {{item.name}}</div>
, the issue is fixed. But why?
Detailed Question
I'm dealing with a directive called parent
that utilizes transclude: true
. Inside the parent
template, there's another directive named repeater
which transcludes contents by dynamically generating an ng-repeat
and compiling it to repeat the transcluded content.
The HTML structure:
<div ng-app="ieTest">
<parent>
<div>{{item.name}}</div>
</parent>
</div>
The code for the parent
directive:
.directive('parent', function($timeout) {
return {
restrict: 'E',
controller: function() {
var ctrl = this;
$timeout(function($timeout) {
ctrl.items = [{
name: 'One'
}, {
name: 'Two'
}, {
name: 'Three'
}];
}, 1000);
$timeout(function($timeout) {
ctrl.items = [{
name: 'Five'
}, {
name: 'Two'
}, {
name: 'Three'
}, {
name: 'Four'
}];
}, 2000);
},
controllerAs: 'ctrl',
transclude: true,
template: '<section><div repeater></div></section>',
link: function() {
// Additional operations can be performed here if needed
}
}
})
The repeater
directive functionality:
.directive('repeater', function($compile) {
return {
restrict: 'A',
require: '^parent',
link: function(scope, element, attrs, parentCtrl, transclude) {
transclude(function(clone) {
element.append(clone);
});
element.attr('ng-repeat', 'item in ctrl.items'); // This ng-repeat is generated dynamically
element.removeAttr('repeater');
$compile(element)(scope);
}
}
})
The Issue at Hand:
In Internet Explorer, when the transcluded content is like
<div>{{item.name}}</div>
, errors occur and the content isn't repeated/displayed as expected. To prevent this error, adding static content inside the element such as <div> {{item.name}}</div>
seems to work. But why does this simple addition solve the problem, and how can it be avoided in the first place?
I've put together a simplified test case demonstrating the problem here. Running it in IE10 will show that nothing happens after 1s and 2s, with
TypeError: Unable to set property 'nodeValue' of undefined or null reference
errors in the console. However, substituting <div>{{item.name}}</div>
with <div> {{item.name}}</div>
or similar seems to resolve the issue without errors.
Could the problem lie in removing the repeater
attribute and recompiling the repeater
directive to create the ng-repeat
? Is there a better approach to achieve the desired outcome?
This complication has been observed in IE10 and IE11 browsers.