diff options
| author | jankuca | 2013-09-23 11:24:42 -0700 |
|---|---|---|
| committer | Vojta Jina | 2013-10-09 15:19:10 -0700 |
| commit | 9efa46ae640cde17487c341daa9a75c0bd79da02 (patch) | |
| tree | addebed6c08a10e5f27a99140d3f5846992d43a2 /src/ng/directive/ngRepeat.js | |
| parent | 64fd2c421ed582c16812d164a8a6f031b8e66287 (diff) | |
| download | angular.js-9efa46ae640cde17487c341daa9a75c0bd79da02.tar.bz2 | |
feat(ngRepeat): use block separator comments
Issue: multi-elements ng-repeat (ng-repeat-start, ng-repeat-end) can contain elements with a trancluding directive. This directive changes content of the row (template) and ng-repeat does not work correctly (when removing/moving rows), because ng-repeat works with the original template (elements).
This changes ng-repeat behavior to traverse the DOM to find current elements everytime we are moving/removing rows (if the template has multiple elements).
Closes #3104
Diffstat (limited to 'src/ng/directive/ngRepeat.js')
| -rw-r--r-- | src/ng/directive/ngRepeat.js | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 78b054ff..bce76411 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -279,7 +279,8 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { trackByIdFn, collectionKeys, block, // last object information {scope, element, id} - nextBlockOrder = []; + nextBlockOrder = [], + elementsToRemove; if (isArrayLike(collection)) { @@ -331,8 +332,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { // lastBlockMap is our own object so we don't need to use special hasOwnPropertyFn if (lastBlockMap.hasOwnProperty(key)) { block = lastBlockMap[key]; - $animate.leave(block.elements); - forEach(block.elements, function(element) { element[NG_REMOVED] = true}); + elementsToRemove = getBlockElements(block); + $animate.leave(elementsToRemove); + forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; }); block.scope.$destroy(); } } @@ -342,6 +344,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 @@ -357,7 +360,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { // do nothing } else { // existing item which got moved - $animate.move(block.elements, null, jqLite(previousNode)); + $animate.move(getBlockElements(block), null, jqLite(previousNode)); } previousNode = block.endNode; } else { @@ -375,11 +378,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.elements = clone; + block.startNode = previousNode && previousNode.endNode ? previousNode.endNode : clone[0]; block.endNode = clone[clone.length - 1]; nextBlockMap[block.id] = block; }); @@ -390,5 +393,22 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { }; } }; + + function getBlockElements(block) { + if (block.startNode === block.endNode) { + return jqLite(block.startNode); + } + + var element = block.startNode; + var elements = [element]; + + do { + element = element.nextSibling; + if (!element) break; + elements.push(element); + } while (element !== block.endNode); + + return jqLite(elements); + } }]; |
