1

I want to add a div runtime to the body like following:

<div>{{test}}</div>

It should be added from outside Angular code like when clicking a button. So, no directive, but just adding the div. Maybe easy question, but I can't find the answer on the web.

Having

function TodoCtrl($scope) {
    $scope.totalTodos = 4;
}

<body ng-app ng-controller="TodoCtrl">
    <span>{{test}}</span> <!-- already works -->
</body>
8
  • You want to add HTML outside of Angular, why? Commented May 13, 2014 at 12:29
  • @tymeJV it's loaded by Ajax. So, html may come from server and may be inserted somewhere in the current html. Commented May 13, 2014 at 12:42
  • @tymeJV then I want to have resolved angular in: <body><span>{{test}}</span><div>{{test}}</div></body> Commented May 13, 2014 at 12:45
  • If it's loaded by AJAX - shouldn't that be done with Angular? Commented May 13, 2014 at 12:49
  • @tymeJV I'm currently embedding Angular in an existing application. Commented May 13, 2014 at 12:54

3 Answers 3

6

If you really need to add HTML from outside of Angular:

// HTML to add
var html = '<div>totalTodos: {{ totalTodos }}</div>';

// Add the HTML
var body = angular.element(document.querySelector('body'));
body.append(html);

// Get the application injector
// Can be retrieved from any element of the application wrapped in angular.element
var $injector = body.injector();

// Get a reference to the newly added HTML element
var divs = document.querySelectorAll('div');
var addedDiv = angular.element(divs[divs.length - 1]);

// Get the scope
var $scope = addedDiv.scope();

// Get the $compile service
var $compile = $injector.get('$compile');

// Compile the element and link it to the scope
$compile(addedDiv)($scope);

// Trigger the digest cycle
$scope.$apply();

Demo: http://plnkr.co/edit/kNKNvEZsv1ChQejO90T6?p=preview

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

1 Comment

This is really cool, because it compiles html code with angular elements! +1 for that. Anyhow, I doubt that the html returned from the server is angular code.
1

You should use ng-repeat to render an array of divs.

Here is some sample controller code:

    $scope.divs = [{
    name: 'I\'m just a default DIV'
    }];

    $scope.add_div = function() {
    // this is simply pushing some new Data to an array
    // that will be rendered in a ng-repeat.
    // You can instead use angulars $http helper
    // to load Data to your scope
    $scope.divs.push({
      name: 'I\'m another DIV'
    })
    }

And this is the html code to render the array of divs:

   <div ng-repeat="div in divs">{{div.name}}</div>

See an example Plunker here

Update:

If you want to render html snippets returned from your server in a ng-repeat you must take some extra action:

  1. Include angular sanitize in your app.
  2. Inside the repeat wrap your output in another div that is rendered as unsafe html (In my plunker achieved via a filter):

    <div ng-repeat="div in divs">
       <div ng-bind-html="div.name | unsafe"></div>
    </div>
    

This way you can render your old html snippets, although I still think this is no good idea.

See the updated Plunker here

Comments

0

You'll want to load in the fragment and then have angular compile it. I have a case where I want to manually insert data from the templateCache into one of my directives and use this:

var template = $templateCache.get('/path/to/file.html');
element.prepend($compile(template)(scope));

The important part of that code for you is the $compile. It will take the raw html, and compile it for the scope that you provide, as if angular loaded it itself.

You can read more about $compile here.

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.