angularjsangularjs-ng-transclude

Required controller cannot be found when using $transclude in required controller


Simplified example of the code....

HTML:

<div ng-app="app">
  <m-carousel>
    <m-carousel-slide>foo</m-carousel-slide>
    <m-carousel-slide>bar</m-carousel-slide>
  </m-carousel>
</div>

JavaScript:

class CarouselDirectiveController {
  constructor($transclude) {
    $transclude(clone => {
      // do something
    }, null, 'slide');
  }
}

class CarouselSlideDirectiveController {
  $onInit() {
    console.log(this.carousel);
  }
}

function carouselDirective() {
  return {
    restrict: 'E',
    replace: true,
    controller: CarouselDirectiveController,
    controllerAs: 'carousel',
    template: '<div class="m-carousel" ng-transclude="slide"></div>',
    transclude: {
      slide: 'mCarouselSlide'
    },
    scope: {},
    bindToController: true
  };
}

function carouselSlideDirective() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    controller: CarouselSlideDirectiveController,
    controllerAs: 'carouselSlide',
    template: '<div class="m-carousel-slide" ng-transclude></div>',
    scope: {},
    bindToController: true,
    require: {
      carousel: '^^mCarousel'
    }
  };
}

angular.module('app.carousel', [])
  .directive('mCarousel', carouselDirective)
  .directive('mCarouselSlide', carouselSlideDirective);

angular.module('app', ['app.carousel']);

This throws the following error:

https://docs.angularjs.org/error/$compile/ctreq?p0=mCarousel&p1=mCarouselSlide

However, if I comment out the $transclude(clone => {}, null, 'slide'); then all is good in the world... How do I access the transcluded content in a parent controller if the controller is required by another?

CodePen: http://codepen.io/anon/pen/KzdNRE?editors=1011


Solution

  • I figured out what this was way back when... If you use $transclude this way you have to remember to manually append the transcluded content. So...

    $transclude(clone => { 
      // do something then... 
      $element.append(clone); 
    }, null, 'slide');