mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-05-31 02:41:32 +08:00
fix(ngRepeat): ensure that the correct (transcluded) scope is used
This commit is contained in:
committed by
Vojta Jina
parent
d71df9f83c
commit
b87e5fc092
@@ -264,7 +264,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
// lastBlockMap on the next iteration.
|
||||
nextBlockMap = {},
|
||||
arrayLength,
|
||||
childScope,
|
||||
key, value, // key/value of iteration
|
||||
trackById,
|
||||
trackByIdFn,
|
||||
@@ -273,6 +272,17 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
nextBlockOrder = [],
|
||||
elementsToRemove;
|
||||
|
||||
var updateScope = function(scope, index) {
|
||||
scope[valueIdentifier] = value;
|
||||
if (keyIdentifier) scope[keyIdentifier] = key;
|
||||
scope.$index = index;
|
||||
scope.$first = (index === 0);
|
||||
scope.$last = (index === (arrayLength - 1));
|
||||
scope.$middle = !(scope.$first || scope.$last);
|
||||
// jshint bitwise: false
|
||||
scope.$odd = !(scope.$even = (index&1) === 0);
|
||||
// jshint bitwise: true
|
||||
};
|
||||
|
||||
if (isArrayLike(collection)) {
|
||||
collectionKeys = collection;
|
||||
@@ -340,8 +350,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
if (block.scope) {
|
||||
// if we have already seen this object, then we need to reuse the
|
||||
// associated scope/element
|
||||
childScope = block.scope;
|
||||
|
||||
nextNode = previousNode;
|
||||
do {
|
||||
nextNode = nextNode.nextSibling;
|
||||
@@ -354,25 +362,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
previousNode = getBlockEnd(block);
|
||||
} else {
|
||||
// new item which we don't know about
|
||||
childScope = $scope.$new();
|
||||
}
|
||||
|
||||
childScope[valueIdentifier] = value;
|
||||
if (keyIdentifier) childScope[keyIdentifier] = key;
|
||||
childScope.$index = index;
|
||||
childScope.$first = (index === 0);
|
||||
childScope.$last = (index === (arrayLength - 1));
|
||||
childScope.$middle = !(childScope.$first || childScope.$last);
|
||||
// jshint bitwise: false
|
||||
childScope.$odd = !(childScope.$even = (index&1) === 0);
|
||||
// jshint bitwise: true
|
||||
|
||||
if (!block.scope) {
|
||||
$transclude(childScope, function(clone) {
|
||||
$transclude(function(clone, scope) {
|
||||
block.scope = scope;
|
||||
clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' ');
|
||||
$animate.enter(clone, null, jqLite(previousNode));
|
||||
previousNode = clone;
|
||||
block.scope = childScope;
|
||||
// Note: We only need the first/last node of the cloned nodes.
|
||||
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
||||
// by a directive with templateUrl when it's template arrives.
|
||||
@@ -380,6 +374,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
nextBlockMap[block.id] = block;
|
||||
});
|
||||
}
|
||||
updateScope(block.scope, index);
|
||||
}
|
||||
lastBlockMap = nextBlockMap;
|
||||
});
|
||||
|
||||
@@ -1175,6 +1175,26 @@ describe('ngRepeat and transcludes', function() {
|
||||
dealoc(element);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should use the correct transcluded scope', function() {
|
||||
module(function($compileProvider) {
|
||||
$compileProvider.directive('iso', valueFn({
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
template: '<div ng-repeat="a in [1]"><div ng-transclude></div></div>',
|
||||
scope: {}
|
||||
}));
|
||||
});
|
||||
inject(function($compile, $rootScope) {
|
||||
$rootScope.val = 'transcluded content';
|
||||
var element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(trim(element.text())).toEqual('transcluded content');
|
||||
dealoc(element);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ngRepeat animations', function() {
|
||||
|
||||
Reference in New Issue
Block a user