aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/directive/ngRepeat.js
diff options
context:
space:
mode:
authorjankuca2013-09-23 11:24:42 -0700
committerVojta Jina2013-10-09 15:19:10 -0700
commit9efa46ae640cde17487c341daa9a75c0bd79da02 (patch)
treeaddebed6c08a10e5f27a99140d3f5846992d43a2 /src/ng/directive/ngRepeat.js
parent64fd2c421ed582c16812d164a8a6f031b8e66287 (diff)
downloadangular.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.js32
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);
+ }
}];