diff --git a/src/directives.js b/src/directives.js index b9779adf17c2..81a532a86336 100644 --- a/src/directives.js +++ b/src/directives.js @@ -789,25 +789,18 @@ angularDirective("ng:hide", function(expression, element){ */ angularDirective("ng:style", function(expression, element){ - // TODO(i): this is inefficient (runs on every $digest) and obtrusive (overrides 3rd part css) - // we should change it in a similar way as I changed ng:class return function(element){ - var resetStyle = getStyle(element); - this.$watch(function(scope){ - var style = scope.$eval(expression) || {}, key, mergedStyle = {}; - for(key in style) { - if (resetStyle[key] === undefined) resetStyle[key] = ''; - mergedStyle[key] = style[key]; - } - for(key in resetStyle) { - mergedStyle[key] = mergedStyle[key] || resetStyle[key]; - } - element.css(mergedStyle); + this.$watch(expression, function(scope, newVal, oldVal){ + var styleToAdd = newVal || {}, + styleToRemove = oldVal || {}, + key; + for(key in styleToRemove) + element.css(key, ''); + element.css(styleToAdd); }); }; }); - /** * @ngdoc directive * @name angular.directive.ng:cloak diff --git a/test/directivesSpec.js b/test/directivesSpec.js index 8c07cf70a183..5e795d2dd711 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -363,37 +363,83 @@ describe("directive", function() { describe('ng:style', function() { + it('should set', function() { var scope = compile('
'); scope.$digest(); expect(element.css('height')).toEqual('40px'); }); + it('should silently ignore undefined style', function() { var scope = compile(''); scope.$digest(); expect(element.hasClass('ng-exception')).toBeFalsy(); }); - it('should preserve and remove previous style', function() { - var scope = compile(''); - scope.$digest(); - expect(getStyle(element)).toEqual({height: '10px'}); - scope.myStyle = {height: '20px', width: '10px'}; - scope.$digest(); - expect(getStyle(element)).toEqual({height: '20px', width: '10px'}); - scope.myStyle = {}; - scope.$digest(); - expect(getStyle(element)).toEqual({height: '10px'}); + describe('preserving styles set before and after compilation', function() { + var scope, preCompStyle, preCompVal, postCompStyle, postCompVal; + + beforeEach(function() { + preCompStyle = 'width'; + preCompVal = '300px'; + postCompStyle = 'height'; + postCompVal = '100px'; + element = jqLite(''); + element.css(preCompStyle, preCompVal); + jqLite(document.body).append(element); + scope = compile(element); + scope.styleObj = {'margin-top': '44px'}; + scope.$apply(); + element.css(postCompStyle, postCompVal); + }); + + afterEach(function() { + element.remove(); + }); + + + it('should not mess up stuff after compilation', function() { + element.css('margin', '44px'); + expect(element.css(preCompStyle)).toBe(preCompVal); + expect(element.css('margin-top')).toBe('44px'); + expect(element.css(postCompStyle)).toBe(postCompVal); + }); + + + it('should not mess up stuff after $apply with no model changes', function() { + element.css('padding-top', '33px'); + scope.$apply(); + expect(element.css(preCompStyle)).toBe(preCompVal); + expect(element.css('margin-top')).toBe('44px'); + expect(element.css(postCompStyle)).toBe(postCompVal); + expect(element.css('padding-top')).toBe('33px'); + }); + + + it('should not mess up stuff after $apply with non-colliding model changes', function() { + scope.styleObj = {'padding-top': '99px'}; + scope.$apply(); + expect(element.css(preCompStyle)).toBe(preCompVal); + expect(element.css('margin-top')).not.toBe('44px'); + expect(element.css('padding-top')).toBe('99px'); + expect(element.css(postCompStyle)).toBe(postCompVal); + }); + + + it('should overwrite original styles after a colliding model change', function() { + scope.styleObj = {'height': '99px', 'width': '88px'}; + scope.$apply(); + expect(element.css(preCompStyle)).toBe('88px'); + expect(element.css(postCompStyle)).toBe('99px'); + scope.styleObj = {}; + scope.$apply(); + expect(element.css(preCompStyle)).not.toBe('88px'); + expect(element.css(postCompStyle)).not.toBe('99px'); + }); }); }); - it('should silently ignore undefined ng:style', function() { - var scope = compile(''); - scope.$digest(); - expect(element.hasClass('ng-exception')).toBeFalsy(); - }); - describe('ng:show', function() { it('should show and hide an element', function() {Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: