diff --git a/src/ng/compile.js b/src/ng/compile.js index 631ddc67cedd..638725e08140 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -3251,16 +3251,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) { + function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) { var trustedContext = getTrustedContext(node, name); - allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing; + var mustHaveExpression = !isNgAttr; + var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr; - var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing); + var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing); // no interpolation found -> ignore if (!interpolateFn) return; - if (name === 'multiple' && nodeName_(node) === 'select') { throw $compileMinErr('selmulti', 'Binding to the \'multiple\' attribute is not supported. Element: {0}', diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index a9659524fd21..f5193fa6a8ca 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -11161,8 +11161,7 @@ describe('$compile', function() { } describe('ngAttr* attribute binding', function() { - - it('should bind after digest but not before', inject(function($compile, $rootScope) { + it('should bind after digest but not before', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBeUndefined(); @@ -11170,7 +11169,7 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should bind after digest but not before when after overridden attribute', inject(function($compile, $rootScope) { + it('should bind after digest but not before when after overridden attribute', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBe('123'); @@ -11178,7 +11177,7 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should bind after digest but not before when before overridden attribute', inject(function($compile, $rootScope) { + it('should bind after digest but not before when before overridden attribute', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBe('123'); @@ -11186,7 +11185,15 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should remove attribute if any bindings are undefined', inject(function($compile, $rootScope) { + it('should set the attribute (after digest) even if there is no interpolation', inject(function() { + element = $compile('')($rootScope); + expect(element.attr('test')).toBeUndefined(); + + $rootScope.$digest(); + expect(element.attr('test')).toBe('foo'); + })); + + it('should remove attribute if any bindings are undefined', inject(function() { element = $compile('')($rootScope); $rootScope.$digest(); expect(element.attr('test')).toBeUndefined(); @@ -11199,6 +11206,8 @@ describe('$compile', function() { })); describe('in directive', function() { + var log; + beforeEach(module(function() { directive('syncTest', function(log) { return { @@ -11219,47 +11228,52 @@ describe('$compile', function() { }); })); - beforeEach(inject(function($templateCache) { + beforeEach(inject(function($templateCache, _log_) { + log = _log_; $templateCache.put('async.html', '

Test

'); })); it('should provide post-digest value in synchronous directive link functions when after overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in synchronous directive link functions when before overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in asynchronous directive link functions when after overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - $rootScope.$digest(); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + $rootScope.$digest(); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in asynchronous directive link functions when before overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - $rootScope.$digest(); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + $rootScope.$digest(); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); }); - it('should work with different prefixes', inject(function($compile, $rootScope) { + it('should work with different prefixes', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBeUndefined(); @@ -11271,14 +11285,14 @@ describe('$compile', function() { expect(element.attr('test3')).toBe('Misko'); })); - it('should work with the "href" attribute', inject(function($compile, $rootScope) { + it('should work with the "href" attribute', inject(function() { $rootScope.value = 'test'; element = $compile('')($rootScope); $rootScope.$digest(); expect(element.attr('href')).toBe('test/test'); })); - it('should work if they are prefixed with x- or data- and different prefixes', inject(function($compile, $rootScope) { + it('should work if they are prefixed with x- or data- and different prefixes', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); @@ -11296,8 +11310,7 @@ describe('$compile', function() { })); describe('when an attribute has a dash-separated name', function() { - - it('should work with different prefixes', inject(function($compile, $rootScope) { + it('should work with different prefixes', inject(function() { $rootScope.name = 'JamieMason'; element = $compile('')($rootScope); expect(element.attr('dash-test')).toBeUndefined(); @@ -11309,7 +11322,7 @@ describe('$compile', function() { expect(element.attr('dash-test3')).toBe('JamieMason'); })); - it('should work if they are prefixed with x- or data-', inject(function($compile, $rootScope) { + it('should work if they are prefixed with x- or data-', inject(function() { $rootScope.name = 'JamieMason'; element = $compile('')($rootScope); expect(element.attr('dash-test2')).toBeUndefined(); @@ -11338,7 +11351,6 @@ describe('$compile', function() { }); }); - it('should keep attributes ending with -end single-element directives', function() { module(function($compileProvider) { $compileProvider.directive('dashEnder', function(log) { @@ -11356,7 +11368,6 @@ describe('$compile', function() { }); }); }); - });