Francisc
Francisc

Reputation: 80415

How to replace the element with ng-transclude

Is it possible to replace the element with ng-transclude on it rather than the entire template element?

HTML:

<div my-transcluded-directive>
    <div>{{someData}}</div>
</div>

Directive:

return {
    restrict:'A',
    templateUrl:'templates/my-transcluded-directive.html',
    transclude:true,
    link:function(scope,element,attrs)
    {

    }
};

my-transcluded-directive.html:

<div>
    <div ng-transclude></div>
    <div>I will not be touched.</div>
</div>

What I am looking for is a way to have <div>{{someData}}</div> replace <div ng-transclude></div>. What currently happens is the transcluded HTML is placed inside the ng-transclude div element.

Is that possible?

Upvotes: 36

Views: 28150

Answers (4)

Andrew Bogdanov
Andrew Bogdanov

Reputation: 638

If you don't have to support IE and Edge you can use display:contents in your css. That will destroy the wrapper on the level of css.

You can read more about this new display propertie here: https://css-tricks.com/get-ready-for-display-contents/

Current browser support (hope to see Edge support in the future): https://caniuse.com/#feat=css-display-contents

Upvotes: 2

danday74
danday74

Reputation: 57016

this works in Angular 1.4.9 (and prob earlier too)

return {
      restrict: 'E',
      replace: true,
      template: '<span data-ng-transclude></span>',
      transclude: true,
      link: function (scope, el, attrs) .........
}

Upvotes: 4

gogoout
gogoout

Reputation: 411

It's easy to create a ng-transclude-replace directive, here is a copycat of the original ng-transclude.

directive('ngTranscludeReplace', ['$log', function ($log) {
              return {
                  terminal: true,
                  restrict: 'EA',

                  link: function ($scope, $element, $attr, ctrl, transclude) {
                      if (!transclude) {
                          $log.error('orphan',
                                     'Illegal use of ngTranscludeReplace directive in the template! ' +
                                     'No parent directive that requires a transclusion found. ');
                          return;
                      }
                      transclude(function (clone) {
                          if (clone.length) {
                              $element.replaceWith(clone);
                          }
                          else {
                              $element.remove();
                          }
                      });
                  }
              };
          }]);

PS:you can also check this link to see the difference between the ng-transclude

Upvotes: 30

swehren
swehren

Reputation: 5744

I think the best solution would probably be to create your own transclude-replace directive that would handle this. But for a quick and dirty solution to your example you could essentially manually place the result of the transclusion where you want:

my-transcluded-directive.html:

<div>
    <span>I WILL BE REPLACED</span>
    <div>I will not be touched.</div>
</div>

Directive:

return {
    restrict:'A',
    templateUrl:'templates/my-transcluded-directive.html',
    transclude:true,
    link:function(scope,element,attrs,ctrl, transclude)
    {
         element.find('span').replaceWith(transclude());
    }
};

Upvotes: 38

Related Questions