Change Angular directive element attribute dynamically
You can do this in the linking function by
- Setting the directive's priority high, so it runs before all others.
- Set it to terminal, so others don't run after it.
- Recompile the element after you make changes to it (such as adding attributes)
For example:
app.directive('hide', function($compile) {
return {
restrict: 'A',
priority: 10000,
terminal: true,
link: function(scope, element, attrs) {
attrs.$set('ngHide', true);
attrs.$set('hide', null);
$compile(element)(scope);
}
};
});
As can be seen on http://plnkr.co/edit/tHNvCxVn2wURO38UtI0n?p=preview
Alan
Updated on October 23, 2020Comments
-
Alan over 3 years
I am trying to create a custom directive which extends the functionality of an existing element. I would like to detect if a certain attribute exists and if not then add it (e.g. ng-class).
I have tried to achieve this during pre-compilation but angular does not react to the addition of the new attribute.
I created a plunker with a simple example using ng-hide.
<input hide type="submit" value="Submit"/>
app.directive('hide', function() { return { restrict: 'A', compile: function(){ return { pre: function(scope, element, attributes, controller, transcludeFn){ attributes.$set("ng-hide", true); }, post: function(scope, element, attributes, controller, transcludeFn){ } } }, }; });
If I add ng-hide="true" in the html then the submit button is hidden correctly. If I leave it to the directive then I can see that the DOM has the element set up correctly but the element is not hidden:
<input hide="" type="submit" value="Submit" ng-hide="true">
Any help appreciated!
-
Alan over 9 yearsYou are a genius, thanks! I didn't need to set terminal in the end; priority and compiling the element (with the directive null) did the trick
-
Michal Charemza over 9 yearsI would keep the
terminal: true
. It might not be technically necessary in the current case, but it does prevent needless recompiling of any other directives on the element.