11

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!

1 Answer 1

20

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

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

2 Comments

You 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
I 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.