mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
fix($compile): properly clone attr.$observers in ng-repeat
The `attr` object was only shallow copied which caused all observers to be shared. Fixing similar issue in ng-* boolean attributes as well as ng-src and ng-href.
This commit is contained in:
parent
4557881cf8
commit
f2106692b1
3 changed files with 40 additions and 2 deletions
|
|
@ -611,6 +611,7 @@ function $CompileProvider($provide) {
|
|||
} else {
|
||||
attrs = shallowCopy(templateAttrs);
|
||||
attrs.$element = jqLite(linkNode);
|
||||
attrs.$observers = {};
|
||||
}
|
||||
element = attrs.$element;
|
||||
|
||||
|
|
|
|||
|
|
@ -283,9 +283,10 @@ forEach(BOOLEAN_ATTR, function(propName, attrName) {
|
|||
var normalized = directiveNormalize('ng-' + attrName);
|
||||
ngAttributeAliasDirectives[normalized] = function() {
|
||||
return {
|
||||
priority: 100,
|
||||
compile: function(tpl, attr) {
|
||||
attr.$observers[attrName] = [];
|
||||
return function(scope, element, attr) {
|
||||
attr.$observers[attrName] = [];
|
||||
scope.$watch(attr[normalized], function(value) {
|
||||
attr.$set(attrName, value);
|
||||
});
|
||||
|
|
@ -301,9 +302,10 @@ forEach(['src', 'href'], function(attrName) {
|
|||
var normalized = directiveNormalize('ng-' + attrName);
|
||||
ngAttributeAliasDirectives[normalized] = function() {
|
||||
return {
|
||||
priority: 100,
|
||||
compile: function(tpl, attr) {
|
||||
attr.$observers[attrName] = [];
|
||||
return function(scope, element, attr) {
|
||||
attr.$observers[attrName] = [];
|
||||
attr.$observe(normalized, function(value) {
|
||||
attr.$set(attrName, value);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1374,6 +1374,41 @@ describe('$compile', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should properly $observe inside ng-repeat', function() {
|
||||
var spies = [];
|
||||
|
||||
module(function($compileProvider) {
|
||||
$compileProvider.directive('observer', function() {
|
||||
return function(scope, elm, attr) {
|
||||
spies.push(jasmine.createSpy('observer ' + spies.length));
|
||||
attr.$observe('some', spies[spies.length - 1]);
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
inject(function($compile, $rootScope) {
|
||||
element = $compile('<div><div ng-repeat="i in items">'+
|
||||
'<span some="id_{{i.id}}" observer></span>'+
|
||||
'</div></div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.items = [{id: 1}, {id: 2}];
|
||||
});
|
||||
|
||||
expect(spies[0]).toHaveBeenCalledOnceWith('id_1');
|
||||
expect(spies[1]).toHaveBeenCalledOnceWith('id_2');
|
||||
spies[0].reset();
|
||||
spies[1].reset();
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.items[0].id = 5;
|
||||
});
|
||||
|
||||
expect(spies[0]).toHaveBeenCalledOnceWith('id_5');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('$set', function() {
|
||||
var attr;
|
||||
beforeEach(function(){
|
||||
|
|
|
|||
Loading…
Reference in a new issue