1

I have the following

compile : function($scope, $element, $attrs, parentCtrl) {
    return {
        pre : function($scope, $element, $attrs, parentCtrl) {
            if($scope.feature == 'drop') {
                $element.find('.playlist').attr('droppable', true);
            }
        },
        post : function($scope, $element, $attrs, parentCtrl) {
            $scope.$parent.$watch('chosen', function(newAsset) {
                if(typeof newAsset != 'undefined' && newAsset.hasOwnProperty('id')) {
                    $scope.list.resource = newAsset.id;
                    $scope.list.loadData();
                }
            });
            }
        }
    }

now.... 'droppable' is a directive. But from what I can see - it's not being handled / compiled. If this is dymanically added within the 'compile-pre' should it be compiled by Angular?

How should I deal with dynamically generated directives?

1
  • I think you cannot add directives to the current element being compiled. Angular's compiler has already passed this element and discovered its directives, before calling your compile function. You can add directives to child elements though. Commented Sep 17, 2014 at 15:53

1 Answer 1

2

Adding new attributes or classnames do not re-trigger a new compile in AngularJS, neither in the compile step itself.

A working approach is to use terminal: true, choose a high priority, add new attributes in link and compile the element there again with a priority limit.

So, we have:

<my-directive></my-directive>

Our directive is defined like:

.directive('myDirective', ['$compile', function($compile) { return {
    priority: 1000,
    terminal: true,
    link: function(scope, element) {
        if (scope.feature) { 
           element.attr('droppable', true);
        }
        $compile($element, null, 1000)(scope);
    }
}}]);

What it does:

  • With priority: 1000 we say angular it should load this directive first (1000 is pretty high) if you let the 'droppable' directive have a default priority of 0.
  • With terminal: true we say angular to skip all directives on that element that comes after it (all with lower priority).
  • In link we add the new attribute to our current element dynamically which should trigger then a new directive in the next $compile step.
  • With $compile(element, transclude, maxPriority); it compiles the current element again, but only with directives that have priority < 1000, which means it excludes our myDirective directive and re-searches and applies all directives inclusive our newly added one.

Take a look at https://docs.angularjs.org/api/ng/service/$compile#-multielement- for more information here. It should jump directly to priority property (although the anchor is called the wrong, but angular's doc site is ... different).

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

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.