How to insert an Angular directive into HTML using an external script?

Asked

Viewed 1,888 times

2

I need to insert a directive within the code of a calendar that is already implemented on a site I’m creating, but I found a problem: in HTML, the directive is printed normally, but Angular does not process it and replaces its content. In this case, I modified the calendar script (the fullCalendar.js) to print the element of a directive of mine from Angular, but it does not compile.

To illustrate, I did the following example: I created a simple directive, which prints "Hello world" where it is placed. I put a tag <ola-mundo> at the beginning of the page, which works as it should. After the page loads, I create a new element <ola-mundo></ola-mundo> using simple Javascript, and placed within the page code. This second is not compiled by Angular.

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {

});

app.directive('olaMundo', function() {
  return {
    restrict: 'E',
    template: '<p>Olá mundo</p>'
  };
});

$(document).ready(function() {
  var elemento = document.createElement('ola-mundo');
  var ola_mundo = document.getElementById('ola-mundo');
  ola_mundo.appendChild(elemento);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body ng-app="app" ng-controller="MainCtrl">
  <p>
    <b>Aqui a diretiva deve imprimir normalmente:</b>
  </p>
  <ola-mundo></ola-mundo>
  <br />
  <br />
  <br />
  <p>
    <b>Aqui a diretiva é injetada por um script, e não funciona:</b>
  </p>
  <div id="ola-mundo"></div>
</body>

I can imagine that the reason for this is for security, for other external scripts not to execute Angular code. So, how else can I inject this directive, since the calendar code is inserted by an external script, which is not part of my code?

  • See the restriction you are using, 'E', 'A' or 'C' or 'EAC'?

  • I recommend taking the course, I did, it’s worth it.

  • @Ivanferrer just used the E in this example, but it doesn’t need more than that. This is the course I attended when I started using Angular a few months ago, but it doesn’t go any deeper. It was great to start, but to deepen the best place is the framework reference.

1 answer

1

This is because you are creating DOM objects without giving Angular the opportunity to compile them.

The code below implements dynamic directive creation and service compilation $compile:

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope,$compile) {

  $scope.adicionarDiretiva = function(){
    angular.element(
      document.getElementById('controlplaceholder'))
    .append($compile("<ola-mundo></ola-mundo>")($scope));
  };});

app.directive('olaMundo', function() {
  return {
    restrict: 'E',
    template: '<p>Olá mundo</p>'
  };});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body ng-app="app" ng-controller="MainCtrl">
  <p>
    <b>Aqui a diretiva deve imprimir normalmente:</b>
  </p>
  <ola-mundo></ola-mundo>
  <br />
  <br />
  <button ng-click='adicionarDiretiva()'>Criar dinamicamente</button>
  
  <br />
  <p>
    <b>Aqui a diretiva é injetada dinamicamente:</b>
  </p>
  <div id="controlplaceholder"></div>
</body>

  • 1

    The code that inserts the <ola-mundo> It’s not within Angular’s code, that’s the problem. It is the calendar script, which is only written using jQuery (and not angular) that inserts this tag into the DOM. But that already explains half the question, which is how to compile the code after Angular itself does it. Another question: why put ($Scope) after $Compile, and without using a . among them?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.