Is it possible to get the innerHTML of a directive

2019-09-04 16:08发布

问题:

I'm working on a style guide and want to add syntax highlighting and code samples dynamically without having to copy/paste and escape the code for each item. The idea is that for each bb-prism directive, I include a bb-sample element that contains my code sample. The bb-prism directive clones the innerHTML of the code sample, creates pre and code elements, and then copies the clone into the code element. It's pretty slick except for when using ng-repeat. Angular seems to remove the ng-repeat before my prism directive can copy it.

<bb-prism>
    <h2>Multiple Addresses</h2>
    <bb-sample>
        <!-- Doesn't work with ng-repeat -->
        <bb-address address="address" ng-repeat="address in addresses"> </bb-address>
    </bb-sample>
</bb-prism>

The expected result is that the sample code should render:

<bb-address address="address" ng-repeat="address in addresses"> </bb-address>

Instead of:

<!-- ngRepeat: address in addresses -->

Here's a working example:

http://codepen.io/rustydev/pen/77fc7dc3e5365f10ebfabd54440f07c7/

回答1:

I played with numerous approaches, including using pre-compile in a stripped down version and couldn't log the html to console.

I propose an alternate approach that will show only the original clean markup and without any angular internal classes added

It uses script tag templates, $templateCache and ng-include.

Here's a rough ( but working) proof of concept setting markup in a textarea for now

View

<div test template ="repeat">
  <h3>repeating items example</h3>

  <!-- Our snippet template -->
  <script type="text/ng-template" id="repeat">
    <div ng-repeat="item in items">{{item}}</div>
  </script>
  <!-- include same template -->
  <ng-include src="'repeat'"></ng-include>

  <!-- source display -->
  <h3>source</h3>
  <textarea style="width:100%"></textarea>

</div>

Directive

.directive('test', function($templateCache) {

  return {
    scope: {template: '@'},
    link: function(scope, elem) {
       var code =$templateCache.get(scope.template);
       elem.find('textarea').val(code.trim())
    }
  }    
});

DEMO

Note that there are gulp and grunt scripts that can compile whole directory of html files into $templateCache also and put them in a run() block

Another thought is use ng-include or templateUrl(function) for each of your html prism components and use $templateCache to get whole block of html and use find() on that to get the uncompiled innerHTML of <bb-sample>

EDIT: More comprehensive demo