feat($compile): support modifying the DOM structure in postlink fn

Support modifying the DOM structure in the post link function of a directive
by creating a defensive copy of the node list, as opposed to a live DOM list.
This is useful for directives to actually replace their entire DOM fragment,
e.g. with the HTML fragment generated by a 3rd party component (Closure, Bootstrap ...).
Fix the indentation of the compileNodes function (was one too little).
This commit is contained in:
Martin Probst 2013-01-08 20:11:51 +01:00 committed by Igor Minar
parent c909f49112
commit cdf6fb19c8
2 changed files with 28 additions and 3 deletions

View file

@ -394,10 +394,16 @@ function $CompileProvider($provide) {
return linkFnFound ? compositeLinkFn : null;
function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) {
var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn;
var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn, i, ii, n;
for(var i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
node = nodeList[n];
// copy nodeList so that linking doesn't break due to live list updates.
var stableNodeList = [];
for (i = 0, ii = nodeList.length; i < ii; i++) {
stableNodeList.push(nodeList[i]);
}
for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
node = stableNodeList[n];
nodeLinkFn = linkFns[i++];
childLinkFn = linkFns[i++];

View file

@ -285,6 +285,25 @@ describe('$compile', function() {
expect(log).toEqual('LOG; LOG');
});
});
it('should allow modifying the DOM structure in post link fn', function() {
module(function() {
directive('removeNode', valueFn({
link: function($scope, $element) {
$element.remove();
}
}));
});
inject(function($compile, $rootScope) {
element = jqLite('<div><div remove-node></div><div>{{test}}</div></div>');
$rootScope.test = 'Hello';
$compile(element)($rootScope);
$rootScope.$digest();
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Hello');
});
})
});
describe('compiler control', function() {