4

I have this attribute directive which under specific conditions needs to add an attribute. But thats not all, I also want to bind the value of this attribute to a property on the $scope. In code (simplified) this looks like

...
.directive('do-magic', function ($timeout) {
    restrict: 'A',
    link: function (scope, element) {
        scope.isMagicDone = false;
        element.attr('is-magic-done', scope.isMagicDone);

        $timeout(function () {
            scope.isMagicDone = true;
        });
    }
});

So, after the $timeout executes I need the is-magic-done value to be true. So the question is: How can I setup a binding programmatically ?

Jeanluca Scaljeri
  • 26,343
  • 56
  • 205
  • 333

1 Answers1

2

One way to do this is to add the attribute to the directive, then $compile the directive attributes again. The trick however, is to remove the directive element before $compile; otherwise you'll have an infinite compile loop.

The result is a call to compile with only the element attributes. Note that the directive itself is not compiled again. Here's an example:

.directive('do-magic', function ($timeout, $compile) {
    restrict: 'A',
    link: function (scope, element, attrs) {
        scope.isMagicDone = false;
        attrs.$set('is-magic-done', '{{isMagicDone}}');

        $timeout(function () {
            scope.isMagicDone = true;
        });

        element.removeAttr('do-magic');
        $compile(element)(scope);
    }
});
Miles P
  • 710
  • 4
  • 12