From 79223eae5022838893342c42dacad5eca83fabe8 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Thu, 24 Oct 2013 12:09:41 -0700 Subject: fix($compile): attribute bindings should not break due to terminal directives Recently we changed the priority of attribute interpolation directive to -100 to ensure that it executes early in the post linking phase. This causes issues with when terminal directives are placed on elements with attribute bindings because the terminal directive will usually have 0 or higher priority which results in attr interpolation directive not being applied to the element. To fix this issue I'm switching the priority back to 100 and making moving the binding setup into the pre-linking function. This means that: - terminal directives with priority lower than 100 will not affect the attribute binding - if a directive wants to add or alter bindings it can do so in the pre-linking phase, as long as the priority of this directive is more than 100 - all post-linking functions will execute after the attribute binding has been set up - all pre-linking functions with directive priority lower than 100 will execute after the attribute bindings have been setup BREAKING CHANGE: the attribute interpolation (binding) executes as a directive with priority 100 and the binding is set up in the pre-linking phase. It used to be that the priority was -100 in rc.2 (100 before rc.2) and that the binding was setup in the post-linking phase. Closes #4525 Closes #4528 Closes #4649 --- test/ng/compileSpec.js | 52 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'test/ng/compileSpec.js') diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 0bba6b37..72165b7e 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -1591,7 +1591,7 @@ describe('$compile', function() { ); - it('should process attribute interpolation at the beginning of the post-linking phase', function() { + it('should process attribute interpolation in pre-linking phase at priority 100', function() { module(function() { directive('attrLog', function(log) { return { @@ -1600,22 +1600,36 @@ describe('$compile', function() { return { pre: function($scope, $element, $attrs) { - log('preLink=' + $attrs.myName); + log('preLinkP0=' + $attrs.myName); }, - post: function($scope, $element) { + post: function($scope, $element, $attrs) { log('postLink=' + $attrs.myName); } } } } - }) + }); + }); + module(function() { + directive('attrLogHighPriority', function(log) { + return { + priority: 101, + compile: function() { + return { + pre: function($scope, $element, $attrs) { + log('preLinkP101=' + $attrs.myName); + } + }; + } + } + }); }); inject(function($rootScope, $compile, log) { - element = $compile('
')($rootScope); + element = $compile('
')($rootScope); $rootScope.name = 'angular'; $rootScope.$apply(); log('digest=' + element.attr('my-name')); - expect(log).toEqual('compile={{name}}; preLink={{name}}; postLink=; digest=angular'); + expect(log).toEqual('compile={{name}}; preLinkP101={{name}}; preLinkP0=; postLink=; digest=angular'); }); }); @@ -1758,6 +1772,32 @@ describe('$compile', function() { expect(element.text()).toBe('AHOJ|ahoj|AHOJ'); }); }); + + + it('should make attributes observable for terminal directives', function() { + module(function() { + directive('myAttr', function(log) { + return { + terminal: true, + link: function(scope, element, attrs) { + attrs.$observe('myAttr', function(val) { + log(val); + }); + } + } + }); + }); + + inject(function($compile, $rootScope, log) { + element = $compile('
')($rootScope); + expect(log).toEqual([]); + + $rootScope.myVal = 'carrot'; + $rootScope.$digest(); + + expect(log).toEqual(['carrot']); + }); + }) }); -- cgit v1.2.3