mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-14 17:53:11 +00:00
fix(ngRepeat): support growing over multi-element groups
This commit is contained in:
parent
b28f96949a
commit
4953b49761
2 changed files with 38 additions and 17 deletions
|
|
@ -245,8 +245,8 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
|
||||||
//watch props
|
//watch props
|
||||||
$scope.$watchCollection(rhs, function ngRepeatAction(collection){
|
$scope.$watchCollection(rhs, function ngRepeatAction(collection){
|
||||||
var index, length,
|
var index, length,
|
||||||
cursor = $element, // current position of the node
|
previousNode = $element[0], // current position of the node
|
||||||
nextCursor,
|
nextNode,
|
||||||
// Same as lastBlockMap but it has the current state. It will become the
|
// Same as lastBlockMap but it has the current state. It will become the
|
||||||
// lastBlockMap on the next iteration.
|
// lastBlockMap on the next iteration.
|
||||||
nextBlockMap = {},
|
nextBlockMap = {},
|
||||||
|
|
@ -288,7 +288,7 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
|
||||||
} else if (nextBlockMap.hasOwnProperty(trackById)) {
|
} else if (nextBlockMap.hasOwnProperty(trackById)) {
|
||||||
// restore lastBlockMap
|
// restore lastBlockMap
|
||||||
forEach(nextBlockOrder, function(block) {
|
forEach(nextBlockOrder, function(block) {
|
||||||
if (block && block.element) lastBlockMap[block.id] = block;
|
if (block && block.startNode) lastBlockMap[block.id] = block;
|
||||||
});
|
});
|
||||||
// This is a duplicate and we need to throw an error
|
// This is a duplicate and we need to throw an error
|
||||||
throw ngError(50, "ngRepeat error! Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}",
|
throw ngError(50, "ngRepeat error! Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}",
|
||||||
|
|
@ -304,8 +304,8 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
|
||||||
for (key in lastBlockMap) {
|
for (key in lastBlockMap) {
|
||||||
if (lastBlockMap.hasOwnProperty(key)) {
|
if (lastBlockMap.hasOwnProperty(key)) {
|
||||||
block = lastBlockMap[key];
|
block = lastBlockMap[key];
|
||||||
animate.leave(block.element);
|
animate.leave(block.elements);
|
||||||
forEach(block.element, function(element) { element[NG_REMOVED] = true});
|
forEach(block.elements, function(element) { element[NG_REMOVED] = true});
|
||||||
block.scope.$destroy();
|
block.scope.$destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -316,24 +316,23 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
|
||||||
value = collection[key];
|
value = collection[key];
|
||||||
block = nextBlockOrder[index];
|
block = nextBlockOrder[index];
|
||||||
|
|
||||||
if (block.element) {
|
if (block.startNode) {
|
||||||
// if we have already seen this object, then we need to reuse the
|
// if we have already seen this object, then we need to reuse the
|
||||||
// associated scope/element
|
// associated scope/element
|
||||||
childScope = block.scope;
|
childScope = block.scope;
|
||||||
|
|
||||||
nextCursor = cursor[0];
|
nextNode = previousNode;
|
||||||
do {
|
do {
|
||||||
nextCursor = nextCursor.nextSibling;
|
nextNode = nextNode.nextSibling;
|
||||||
} while(nextCursor && nextCursor[NG_REMOVED]);
|
} while(nextNode && nextNode[NG_REMOVED]);
|
||||||
|
|
||||||
if (block.element[0] == nextCursor) {
|
if (block.startNode == nextNode) {
|
||||||
// do nothing
|
// do nothing
|
||||||
cursor = block.element;
|
|
||||||
} else {
|
} else {
|
||||||
// existing item which got moved
|
// existing item which got moved
|
||||||
animate.move(block.element, null, cursor);
|
animate.move(block.elements, null, jqLite(previousNode));
|
||||||
cursor = block.element;
|
|
||||||
}
|
}
|
||||||
|
previousNode = block.endNode;
|
||||||
} else {
|
} else {
|
||||||
// new item which we don't know about
|
// new item which we don't know about
|
||||||
childScope = $scope.$new();
|
childScope = $scope.$new();
|
||||||
|
|
@ -346,12 +345,14 @@ var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
|
||||||
childScope.$last = (index === (arrayLength - 1));
|
childScope.$last = (index === (arrayLength - 1));
|
||||||
childScope.$middle = !(childScope.$first || childScope.$last);
|
childScope.$middle = !(childScope.$first || childScope.$last);
|
||||||
|
|
||||||
if (!block.element) {
|
if (!block.startNode) {
|
||||||
linker(childScope, function(clone) {
|
linker(childScope, function(clone) {
|
||||||
animate.enter(clone, null, cursor);
|
animate.enter(clone, null, jqLite(previousNode));
|
||||||
cursor = clone;
|
previousNode = clone;
|
||||||
block.scope = childScope;
|
block.scope = childScope;
|
||||||
block.element = clone;
|
block.startNode = clone[0];
|
||||||
|
block.elements = clone;
|
||||||
|
block.endNode = clone[clone.length - 1];
|
||||||
nextBlockMap[block.id] = block;
|
nextBlockMap[block.id] = block;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -753,4 +753,24 @@ describe('ngRepeat ngAnimate', function() {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should grow multi-node repeater', inject(function($compile, $rootScope) {
|
||||||
|
$rootScope.show = false;
|
||||||
|
$rootScope.books = [
|
||||||
|
{title:'T1', description: 'D1'},
|
||||||
|
{title:'T2', description: 'D2'}
|
||||||
|
];
|
||||||
|
element = $compile(
|
||||||
|
'<div>' +
|
||||||
|
'<dt ng-repeat-start="book in books">{{book.title}}:</dt>' +
|
||||||
|
'<dd ng-repeat-end>{{book.description}};</dd>' +
|
||||||
|
'</div>')($rootScope);
|
||||||
|
|
||||||
|
$rootScope.$digest();
|
||||||
|
expect(element.text()).toEqual('T1:D1;T2:D2;');
|
||||||
|
$rootScope.books.push({title:'T3', description: 'D3'});
|
||||||
|
$rootScope.$digest();
|
||||||
|
expect(element.text()).toEqual('T1:D1;T2:D2;T3:D3;');
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue