Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you transclude into a child directive in Angular?

I want to be able to do something like this in my app:

<pill-autocomplete>
  <pill-template>{{item.name}}</pill-template>
</pill-autocomplete>

Where pill-autocomplete has a template that transcludes into a child directive like this:

<pills ng-transclude="pillTemplate"></pills>
<input type="text">

It doesn't seem possible given that ng-transclude creates scope and the <pills> directive has an isolate scope.

One way I have thought of accomplishing this is by injecting the pill template inside the autocomplete's template function. The problem with that is that it loses the transclusion scope. I'd also have to do this in every directive that has similar behavior with pills.

Is there any other way to accomplish this in angular 1.x?

like image 945
Walt Avatar asked Nov 19 '16 21:11

Walt


1 Answers

The problem is that by the time you transclude data from pill-autocomplete to pills you already have deleted the content inside pills.

The transclusion replaces the content under the directive template so the content in the pills directive template simply cannot be loaded because has been overridden by the transclusion.

My suggestion is simple, not use directly the tag with the ng-transclude inside, use an internal div to make possible the directive to load its content

angular.module('app', []);
  var app = angular.module('app');

  'use strict';

  var app =  angular.module('app');

  app.controller('testController', [
    function () {
      var vm = this;
      vm.name = 'Jimmy';
    }]);

  app.directive('pillAutocomplete', function () {
    return {
      priority: 100,
      restrict: 'E',
      transclude: true,
      template: '<pills><p>From Pill-Autocomplete</p><div ng-transclude><div></pills>'
    };
  });

  app.directive('pills', function () {
    return {
      restrict: 'E',
      transclude: true,
      link: function (scope, element, attrs) {
        scope.style = true;
      },
      template: '<p>Inside Pills</p><div ng-class="{pillscolor : style}" ng-transclude></div>'
    };
  });
.pillscolor{
  color: green;
  font-size: 20px;
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<article ng-app="app">
<section ng-controller="testController as test">
 Controller scope - {{test.name}}
  <pill-autocomplete>
     From controller - {{test.name}}
  </pill-autocomplete>
</section>
</article>
like image 101
Gordo Avatar answered Nov 14 '22 23:11

Gordo