3

Is it possible to somehow add directive as simple attribute in compile function and let angular handle compiling of added directive?

Provided example bellow obviously does not work, but my proper question would be, what is the cleanest way to achieve that?

var app = angular.module('app', []);

app.directive('testOne', function ($compile) {
  return {
    restrict: 'A',
    priority: 10000,
    compile: function (element, attrs) {
      
      element.attr('test-two', '');
    }
  };
});

app.directive('testTwo', function () {
  return {
    restrict: 'A',
    priority: 10,
    compile: function (element, attrs) {
      console.log(2);
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">


  <div test-one></div>


</div>

1 Answer 1

4

In the link phase, you can call $compile(element)(scope) to recompile the element to allow AngularJS to pick up the newly added directive. However, to prevent an infinite loop (since your initial directive will also be re-compiled), you should remove the initial directive's attribute first:

link: function (scope, element) {
    element.removeAttr('test-one');
    element.attr('test-two', '');

    $compile(element)(scope);
}

Edit: You may also want to set terminal: true on your initial directive to prevent other directives from kicking in before your attribute massaging is done. You may also have to play around with the priority of the directive for similar reasons.

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

5 Comments

Ok so this is the cleanest way :) I wanted to know if I can somehow avoid multiple compilations. Thanks!
Another question if you know answer perhaps. How can I programatically change attribute of an element so that $observe in another directive will trigger? I tried attrs.$set and no luck.
If the directive is not actively watching for changes to the attribute expression, you're out of luck. I'd peek into to source code of the other directive (if it's not your directive) and see if there's any watching going on.
Yes, except another $compile :) don't like this though..:) Thanks
+1 @AtesGoral "to prevent an infinite loop (since your initial directive will also be re-compiled), you should remove the initial directive's attribute first" - Thank You

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.