fix($compile): relax the restriction that directives can not add siblings

Relax the restriction that directives can not add siblings
This commit is contained in:
Misko Hevery 2012-04-03 14:15:42 -07:00
parent 15c1fe3929
commit 7e86eacf30
2 changed files with 34 additions and 15 deletions

View file

@ -350,7 +350,7 @@ function $CompileProvider($provide) {
var linkingFns = [],
directiveLinkingFn, childLinkingFn, directives, attrs, linkingFnFound;
for(var i = 0, ii = nodeList.length; i < ii; i++) {
for(var i = 0; i < nodeList.length; i++) {
attrs = new Attributes();
// we must always refer to nodeList[i] since the nodes can be replaced underneath us.
@ -374,10 +374,6 @@ function $CompileProvider($provide) {
return linkingFnFound ? linkingFn : null;
/* nodesetLinkingFn */ function linkingFn(scope, nodeList, rootElement, boundTranscludeFn) {
if (linkingFns.length != nodeList.length * 2) {
throw Error('Template changed structure!');
}
var childLinkingFn, directiveLinkingFn, node, childScope, childTransclusionFn;
for(var i=0, n=0, ii=linkingFns.length; i<ii; n++) {

View file

@ -242,16 +242,39 @@ describe('$compile', function() {
});
it('should prevent changing of structure', inject(
function($compile, $rootScope){
element = jqLite("<div><div log></div></div>");
var linkFn = $compile(element);
element.append("<div></div>");
expect(function() {
linkFn($rootScope);
}).toThrow('Template changed structure!');
}
));
it('should allow changing the template structure after the current node', function() {
module(function($compileProvider){
$compileProvider.directive('after', valueFn({
compile: function(element) {
element.after('<span log>B</span>');
}
}));
});
inject(function($compile, $rootScope, log){
element = jqLite("<div><div after>A</div></div>");
$compile(element)($rootScope);
expect(element.text()).toBe('AB');
expect(log).toEqual('LOG');
});
});
it('should allow changing the template structure after the current node inside ngRepeat', function() {
module(function($compileProvider){
$compileProvider.directive('after', valueFn({
compile: function(element) {
element.after('<span log>B</span>');
}
}));
});
inject(function($compile, $rootScope, log){
element = jqLite('<div><div ng-repeat="i in [1,2]"><div after>A</div></div></div>');
$compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('ABAB');
expect(log).toEqual('LOG; LOG');
});
});
});
describe('compiler control', function() {