0

I am trying to modify an Angular template before any other directive is triggered, in particular interpolation. I am doing this through the compile option in the directive definition.

Here is my test code:

<!doctype html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script> <script> angular.module('soQuestion', []) .directive('example', function () { return { compile: function (tElement, tAttrs) { if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) { tElement.attr('foo', 'prefix-' + tAttrs.foo); console.log(tElement.attr('foo')); } } }; }) .controller('controller', function($scope) { $scope.value = 'something'; }); </script> </head> <body ng-app="soQuestion"> <div ng-controller="controller"> <div example foo="keyword_{{value}}"></div> </div> </body> </html> 

However, the final result that I get is <div foo="keyword_something"></div> instead of <div foo="prefix-keyword_something"></div>, even if the compile function was triggered properly. What is going on here?

2

2 Answers 2

1

Its a directive priority issue, and admittedly I still don't completely understand. But don't for get that {{}} is itself a directive. Its getting applied in some order with yours, and overwriting your manipulation. If its terminal and high priority, it clears up.

DEMO

angular.module('soQuestion', []) .directive('example', function () { return { priority: 1000, terminal : true, compile: function (tElement, tAttrs) { if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) { tElement.attr('foo', 'prefix-' + tAttrs.foo); console.log(tElement.attr('foo'), tElement[0]); } return function(){}; } }; }) .controller('controller', function($scope) { $scope.value = 'something'; }); 

because this breaks the {{}} I would consider compiling the attr manually as well.

Sign up to request clarification or add additional context in comments.

Comments

0
angular.module('soQuestion', []) .directive('example', function () { return { compile: function (tElement, tAttrs) { if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) { // Change the tAttrs hash instead of the element itself tAttrs.foo = 'prefix-' + tAttrs.foo; // Change the element too, in case no interpolation is present tElement.attr('foo', tAttrs.foo); console.log(tElement.attr('foo')); } } }; }) 

Explanation: the interpolate directive does check for changes in the attribute value. However it doesn't look again on the DOM node itself but on the tAttrs hash.


Old pessimistic answer:

I don't think it's possible to achieve the desired result.

Looking at Angular's source, collectDirectives puts together the list of directives that affect a certain node. Their respective compile functions are collected and then sorted by priority. The problem is that the compile function of {{}} is then bound to keyword_{{value}} and is not affected by the example directive.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.