Tommy McGuire
Tommy McGuire

Reputation: 13

How to dynamically nest directives in AngularJS

New to Angular and need some assistance.

I have a block of HTML content that will be coming from a database that will contain a group of widgets. These are simple widgets that will essentially render out various elements, but for the purposes of this question we'll assume they're all basic HTML inside.

Those widgets are included in an unpredictable way, so my first thought was to use directives to render the HTML. So, we'd have something like:

<div widget data="This is the content."></div>

So I've got a directive that will place the value of data into the div. Easy enough!

Now, how would I go about nesting those widgets? So, how would I get something like:

 <div widget data="Welcome! ">
    <div widget data="This is some inside content."></div>
 </div>

to render out:

Welcome! This is some inside content.

... because the issue I'm noticing is that if I place anything inside the directive HTML, it essentially gets ignored since it gets replaced with its own result (thus only echoing out Welcome!).

I realize I may be going the wrong direction on this in the first place, so any insight would be greatly appreciated. Thanks so much!

Upvotes: 0

Views: 108

Answers (1)

PSL
PSL

Reputation: 123739

This is where you need to use the transclusion feature of the directive combined with ng-transclude directive.

Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.

Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.

A very basic version of transclusion of content based on your example might look something like this:

.directive('widget', function() {
  return {
    transclude: true,//Set transclusion
    template: '{{text}} <section ng-transclude></section>', <!-- set where you need to present the transcluded content -->
    scope: {
      text: "@"
    }
  }
});

Demo

angular.module('app', []).directive('widget', function() {
  return {
    transclude: true,
    template: '{{text}} <section ng-transclude></section>',
    scope: {
      text: "@"
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <span widget data-text="Welcome! ">
    <div widget data-text="This is some inside content.">
      <span widget data-text="This is some inside inside content."></span>
    </div>
  </span>
</div>

Upvotes: 2

Related Questions