2

I've always been using the $compile service to dynamically inject an element but just got beaten by something unexpected. So, here is how I used to inject a directive:

angular
    .module('app', [])
    .directive('test', function () {
        return {
            restrict: 'E',
            controller: function () {
                console.log('hey, just got compiled!')
            }
        }
    })
    .run(function ($compile, $rootScope) {
        var $scope = $rootScope.$new()
        var directive = $compile('<test></test>')($scope)
        var app = angular.element(document.querySelector('[ng-app]'))

        app.append(directive)
    })

In this fiddle, you can see that the directive seems to be compiled twice. So I removed the $compile trick and it's working just fine, the directive is compiled once:

angular
    .module('app', [])
    .directive('test', function () {
        return {
            restrict: 'E',
            controller: function () {
                console.log('hey, just got compiled!')
            }
        }
    })
    .run(function ($compile, $rootScope) {
        var app = angular.element(document.querySelector('[ng-app]'))
        app.append('<test></test>')
    })

fiddle

So, is .append compiling the directive?

I am a bit confused as I've always seen the first version as the recommended one and I can't find anything related to compilation in the jqLike's implementation of "append".

Gabin
  • 920
  • 10
  • 26

1 Answers1

1

This is because run phase occurs before the DOM is compiled the first time. It has nothing to do with using append()

The $compile you are using in run() is not needed for this use case.

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • Thank you very much, that makes perfect sense! While I wasn't able to find a detailed documentation of angular's run cycle, I found this answer to be particularly interesting: http://stackoverflow.com/a/20664122/2373066 – Gabin Mar 09 '16 at 14:39