From 624fd80854b912ab5fe6b282264f88f42ab594b1 Mon Sep 17 00:00:00 2001 From: jankuca Date: Mon, 23 Sep 2013 11:24:42 -0700 Subject: [PATCH] feat(ngRepeat): use block separator comments Closes #3104 --- src/ng/directive/ngRepeat.js | 21 +++++- test/BinderSpec.js | 27 ++++++- test/ng/directive/ngClassSpec.js | 10 +-- test/ng/directive/ngRepeatSpec.js | 121 ++++++++++++++++++++++++++---- 4 files changed, 151 insertions(+), 28 deletions(-) diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 50be2a618e68..d31f2d201bba 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -327,8 +327,21 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { for (key in lastBlockMap) { if (lastBlockMap.hasOwnProperty(key)) { block = lastBlockMap[key]; - $animate.leave(block.elements); - forEach(block.elements, function(element) { element[NG_REMOVED] = true}); + + var elementsToRemove = []; + var elementToRemove = block.startNode; + elementsToRemove.push(elementToRemove); + + if (block.startNode !== block.endNode) { + do { + elementToRemove = elementToRemove.nextSibling; + if (!elementToRemove) break; + elementsToRemove.push(elementToRemove); + } while (elementToRemove !== block.endNode); + } + + $animate.leave(angular.element(elementsToRemove)); + forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; }); block.scope.$destroy(); } } @@ -338,6 +351,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { key = (collection === collectionKeys) ? index : collectionKeys[index]; value = collection[key]; block = nextBlockOrder[index]; + if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1].endNode; if (block.startNode) { // if we have already seen this object, then we need to reuse the @@ -371,10 +385,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { if (!block.startNode) { linker(childScope, function(clone) { + clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' '); $animate.enter(clone, null, jqLite(previousNode)); previousNode = clone; block.scope = childScope; - block.startNode = clone[0]; + block.startNode = previousNode && previousNode.endNode ? previousNode.endNode : clone[0]; block.elements = clone; block.endNode = clone[clone.length - 1]; nextBlockMap[block.id] = block; diff --git a/test/BinderSpec.js b/test/BinderSpec.js index 3c204b64c48b..b553c68dcfd0 100644 --- a/test/BinderSpec.js +++ b/test/BinderSpec.js @@ -96,7 +96,9 @@ describe('Binder', function() { ''); items.unshift({a: 'C'}); @@ -105,8 +107,11 @@ describe('Binder', function() { ''); items.shift(); @@ -115,7 +120,9 @@ describe('Binder', function() { ''); items.shift(); @@ -134,6 +141,7 @@ describe('Binder', function() { ''); })); @@ -148,15 +156,15 @@ describe('Binder', function() { $rootScope.items = items; $rootScope.$apply(); - expect(element[0].childNodes.length - 1).toEqual(0); + expect(element[0].childNodes.length).toEqual(1); items.name = 'misko'; $rootScope.$apply(); - expect(element[0].childNodes.length - 1).toEqual(1); + expect(element[0].childNodes.length).toEqual(3); delete items.name; $rootScope.$apply(); - expect(element[0].childNodes.length - 1).toEqual(0); + expect(element[0].childNodes.length).toEqual(1); })); it('IfTextBindingThrowsErrorDecorateTheSpan', function() { @@ -223,13 +231,19 @@ describe('Binder', function() { '
'+ '' + ''+ + '' + ''+ + '' + '
'+ + '' + '
'+ '' + ''+ + '' + ''+ + '' + '
' + + '' + ''); })); @@ -306,15 +320,18 @@ describe('Binder', function() { '
' + '')($rootScope); $rootScope.$apply(); + var d1 = jqLite(element[0].childNodes[1]); - var d2 = jqLite(element[0].childNodes[2]); + var d2 = jqLite(element[0].childNodes[3]); expect(d1.hasClass('o')).toBeTruthy(); expect(d2.hasClass('e')).toBeTruthy(); expect(sortedHtml(element)).toBe( '
' + '' + '
' + + '' + '
' + + '' + '
'); })); @@ -420,7 +437,9 @@ describe('Binder', function() { ''); })); diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index f0989f4a9531..a788e45255b5 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -166,7 +166,7 @@ describe('ngClass', function() { element = $compile('