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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.