angularjsangularjs-compile

AngularJS $compile removes previous compiled-element


Background

We have an old application written i jQuery and Handlebars and we're migrating part by part to AngularJS (this work began many years ago and was never finished, hence AngularJS).

Problem

To migrate part by part we're injecting directives into the old Handelbars-templates for several different reasons. The problem that I'm facing is that I can't $compile two different directives in the same view because, what it seems, one of the directives empties the other directive.

I can get around this by setting a timeout around one directive but I don't see that as a valid workaround so I'm hoping that it can be done in some other way.

Relevant code

This is how we load directives into a Handlebars-template:

<div id="ng-wrapper"></div>
<script type="text/javascript">
    $(document).ready(function() {
        angular.element(document).injector().invoke(['$compile', function ($compile) {
            var wrapperEl = $('ng-wrapper');
            var scope = angular.element(wrapperEl).scope();
            wrapperEl.append($compile('<directive-one></directive-one>')(scope);
        }]);
    });
</script>

If I try to add a second directive into that invoke-function one directive is emptied and only one directive is showing, like this:

<div id="ng-wrapper"></div>
<script type="text/javascript">
    $(document).ready(function() {
        angular.element(document).injector().invoke(['$compile', function ($compile) {
            var wrapperEl = $('ng-wrapper');
            var scope = angular.element(wrapperEl).scope();
            wrapperEl.append($compile('<directive-one></directive-one>')(scope);
            wrapperEl.append($compile('<directive-two></directive-two>')(scope);
        }]);
    });
</script>

If I however add a timeout it works, like this:

<div id="ng-wrapper"></div>
<script type="text/javascript">
    $(document).ready(function() {
        angular.element(document).injector().invoke(['$compile', '$timeout', function ($compile, $timeout) {
            var wrapperEl = $('ng-wrapper');
            var scope = angular.element(wrapperEl).scope();
            wrapperEl.append($compile('<directive-one></directive-one>')(scope);
            $timeout(function () {
                wrapperEl.append($compile('<directive-two></directive-two>')(scope);
            }, 500);
        }]);
    });
</script>

I've used AngularJS for many years but haven't touched $compile before so hopefully it's something I'm doing wrong here :)


Solution

  • Found out that it works as the first example (see the Plunker-URL in my comment) and that it's something else wrong in our application.