1

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).

9
  • why would this be even necessary? Any time you are using document.getElementById(), you are trying to program against the DOM. Angular doesn't need to be developed in this manner. How did the HTML content get into those elements without angular knowing about it, or being able to be told by the server when the page was rendered? Something isn't adding up here. Commented Jul 10, 2015 at 23:07
  • can you show a bit more about what it is you are actually trying to do, and why you can't use ng-repeat on the data, instead of the rendered HTML? As it stands right now, this is definitely an XY Question. see meta.stackexchange.com/questions/66377/what-is-the-xy-problem/… Commented Jul 10, 2015 at 23:09
  • I was trying to keep the question simple, but perhaps I did not include enough information. My ng-repeat is inside a directive template. My directive element contains transcluded elements which I grab in link() with the transclude() function and disperse into a set of arrays, and I'd like each array to display in a different ng-repeated div. I'll update the original question with this information. Commented Jul 10, 2015 at 23:13
  • This appears to be an anti pattern. What are you trying to achieve by solving this? Commented Jul 10, 2015 at 23:15
  • that is a bit closer to what your problem is, but why render the elements into a transclusion if you are just going to tear the HTML apart? why not pass the data as parameters to the directive directly? Commented Jul 10, 2015 at 23:17

2 Answers 2

1

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

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

Comments

1

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.

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.