JediusX
JediusX

Reputation: 127

Directive with ng-transclude wraps html in ng-transclude element

I have a directive with an ng-repeat in the template, but I also want to have an ng-transclude after the repeater to allow a user to insert their own content. The problem is that the custom content is wrapped in an ng-transclude element when it is rendered and I don't want that.

Directive:

    angular.module("MyModule", [])
  .directive('myDirective', [function () {
    return {
      restrict: 'EA',
      transclude: true,
      replace: true,
      scope: {},
      templateUrl: 'templates/template_view.html',
      link: function (scope, element, attrs) { 
        scope.nodes = [
          {
            "imageSource": "",
            "title": "Sample Title",
            "body": "Lorem ipsum and some other stuffs",
            "readMore": "",
            "date": "Mar 20"
          }
        ];

      }
    };
  }]);

Template:

<section>
  <div class="someClass" ng-repeat="node in nodes">
    <div>
      <img src="{{node.imageSource}}" alt="Picture">
    </div>
    <div class="content bounce-in">
      <h2>{{node.title}}</h2>
      <p>{{node.body}}</p>
      <a href="{{node.readMore}}" ng-show="{{node.readMore}}">Read more</a>
      <span>{{node.date}}</span>
    </div>
  </div>
  <div ng-transclude></div>
</section>

Use:

<div my-directive>
  <div class="someClass">
    <h2>Title of section 1</h2>
    <p>Lorem ipsum dolor </p>
    <span class="cd-date">Jan 14</span>
  </div>
  <div class="someClass">
    <h2>Title of section 2</h2>
    <p>Lorem ipsum dolor</p>
    <span class="cd-date">Jan 18</span>
  </div>
</div>

What gets output:

<section my-directive="">
  <!-- ngRepeat: node in nodes -->
  <div class="someClass" ng-repeat="node in nodes">
    <div>
      <img src="" alt="Picture">
    </div>

    <div class="content bounce-in">
      <h2>Sample Title</h2>
      <p>Lorem ipsum and some other stuffs</p>
      <a href="" ng-show="">Read more</a>
      <span>Mar 20</span>
    </div>
  </div>
  <!-- end ngRepeat: node in nodes -->
  <div ng-transclude="">
    <div class="someClass">
      <h2>Title of section 1</h2>
      <p>Lorem ipsum dolor</p>
      <span class="cd-date">Jan 14</span>
    </div>
  </div>
  <div class="someClass">
    <h2>Title of section 2</h2>
    <p>Lorem ipsum dolor </p>
    <span class="cd-date">Jan 18</span>
  </div>
  </div>

  </div>
</section>

I don't want the <div ng-transclude> element wrapping the transcluded data.

Upvotes: 0

Views: 794

Answers (1)

idan
idan

Reputation: 484

You can make use of the transclude function passed to your directive's comtroller and link functions (in your case the link function which anyway is the more recommended approach) Angular docs.
You get the clone of the transcluded content and you can do whatever you want with it:

angular.module("MyModule", [])
  .directive('myDirective', [function () {
    return {
      restrict: 'EA',
      transclude: true,
      replace: true,
      scope: {},
      templateUrl: 'templates/template_view.html',
      link: function (scope, element, attrs, ctrls, transcludeFn) { 
        scope.nodes = [
          {
            "imageSource": "",
            "title": "Sample Title",
            "body": "Lorem ipsum and some other stuffs",
            "readMore": "",
            "date": "Mar 20"
          }
        ];
        
        transcludeFn(function (clone) {
          element.find('a-selector-for-the-ng-translude-element').after(clone).remove();
        });

      }
    };
  }]);

Haven't tested the above code...

Also, re-consider the use of replace: true as it's deprecated since Angular 1.3

Upvotes: 1

Related Questions