1

Here's the issue. I need to pass a directive2 into directive1. Directive1 has a dynamic templateUrl. A template has a section that would host transcluded code (another directive). This does not work unless I surround element.find (below) with a $timeout. Once the page is rendered, the directive will be embedded into the template. But I can't get it to work without the timeout.

<directive1>
  <directive2></directive>
</directive1>

Directive1

app.directive("directive1", function() {
    return {
        replace: true,
        transclude: true,
        template: '<ng-include src="getTemplateUrl()" />',
        scope: {
            id: "="
        },
        link: function (scope, element, attrs, controller, transclude) {
            scope.getTemplateUrl = function () {
                return "template" + scope.id + ".html";
            };

            element.find(".placeholderForDirective2").append(transclude());

        }
    }
})

Template1:

<div>
    <div class="placeholderForDirective2"></div>
    <div>blah blah blah</div>
</div>

2 Answers 2

2

ngInclude provides a couple of options to be notified when the template is loaded.

You can use the onload attribute to evaluate an expression when the template is loaded:

<ng-include src="getTemplateUrl()" onload="myFunction()" />

It also emits events that you can listen for, specifically the $includeContentLoaded event.

scope.$on('$includeContentLoaded', myFunction);

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

2 Comments

This is a much much better approach than rummaging around in the DOM with element.find().
That was 6 seconds indeed :D
1

This is absolutely expected: ng-include is asynchronous, while the code in the link function is synchronous. The element.find() will run most certainly before Angular has had the time to fetch the "template" + scope.id + ".html".

You can listen to ng-include's '$includeContentLoaded' event and then call element.find():

scope.$on('$includeContentLoaded', function() {
    element.find(".placeholderForDirective2").append(transclude());
});

1 Comment

You beat me by six seconds :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.