Josh Sherick
Josh Sherick

Reputation: 2161

Is it possible to interpolate an HTML element into the document in AngularJS?

Say in my controller somewhere I have:

$scope.elements = [document.getElementById('a'), document.getElementById('b')];

and I have valid elements somewhere in the document with IDs of a and b.

I'd like to interpolate these elements directly in an HTML template, without writing JavaScript. I tried the following, and it did not work.

<div ng-repeat="e in elements">
    {{ e }}
</div>

Is this possible?

More information about what I'm doing:

I have content (several custom directive elements which load up their own data via AJAX) that I want to disperse between several columns. The column of the content elements will change, and the number of columns will change.

<column-resizer options="columnResizerOptions">
    <content1></content1>
    <content2></content2>
    ...
</column-resizer>

The template for columnResizer currently looks like this:

<ng-transclude></ng-transclude>
<div ng-repeat="column in columns">
    <div ng-repeat="element in column">
        {{ element }}
    </div>
</div>

columnResizerOptions is information about how to resize the columns and where to place the content in the columns. In the link function for the columnResizer, I use transclude to grab content1-contentn and place them in arrays corresponding to the column they should be in, which I ngRepeat through in my template (above).

Upvotes: 1

Views: 862

Answers (2)

Estus Flask
Estus Flask

Reputation: 222419

It is possible.

$scope.elements = [ (document.getElementById('a') || {}).outerHTML ];

and

<div ng-repeat="e in elements">
    <div ng-bind-html="e"></div>
</div>

You won't get data binding this way. You can use innerHTML or jqLite html() instead to get rid of extra wrappers.

get them into the DOM without using append, as it would be cleaner.

It wouldn't. A directive with nested directives or with DOM modifications in link is proper way in this case, you don't have to use data binding everywhere just because Angular promotes it.

Upvotes: 1

yvesmancera
yvesmancera

Reputation: 2925

Not sure why you wouldn't treat your whole app the "Angular way", but you could write a directive to do this:

angular.module('demoApp', [])
  .directive('interpolateHtml', function() {
    return {
      restrict: 'A',
      scope: {
        htmlElement: '='
      },
      link: function postLink(scope, element) {
        element.append(scope.htmlElement);
      }

    }

  })

And use it in your HTML like this:

<div ng-repeat="e in elements">
  <div interpolate-html html-element="e"></div>
</div>

Here's a working plnkr: http://plnkr.co/edit/5NvMA1x0C8TcwdLO2FNK?p=preview

Upvotes: 1

Related Questions