angularjs test 1: transclusion

by Richard Hunter

HTML

<div ng-app="myApp" ng-controller="MyController">
  <h1>Angular experiment: Transclusion</h1>

  <rh-foo>
    <foo-one>content 1</foo-one>
    <foo-two>content 2</foo-two>
  </rh-foo>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.js" integrity="sha512-klc+qN5PPscoGxSzFpetVsCr9sryi2e2vHwZKq43FdFyhSAa7vAqog/Ifl8tzg/8mBZiG2MAKhyjH5oPJp65EA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div>

the purpose of the transclude function that is passed as the fifth argument of the link function is to facilitate the adding of transcluded content somewhere within the directive's element. in fact, it's not needed for ordinary use since the `ng-transclude` directive handles every possible use case. the `ng-transclude` directive calls the transclude function for you. it's unfortunate that this remains part of the public API as it is liable only to cause confusion. the example here shows multi-slot transclusion implemented manually. note that the transclude function requires the slot for the transcluded content as the third parameter. this is not documented
</div>

CSS

.foo {
  background: hotpink;
  padding: 10px;
}

.foo .transcluded {
  background: lightgoldenrodyellow;
  padding: 10px;
}

JavaScript

angular.module('myApp', [])
  .controller('MyController', ['$scope', (scope) => {}])
  .directive('rhFoo', () => {
    return {
      template: `
      	<div class="foo">
        	<div>before</div>
        	<div class="transcluded one"></div>
          in between
          <div id="two" class="transcluded two"></div>
          <div>after</div>
        </div>
      `,
      transclude: {
        one: 'fooOne',
        two: 'fooTwo',
      },
      link: (scope, element, attributes, controller, transcludeFn) => {

        const cloneAttachFnOne = (clone) => {
          element[0].querySelector('.one').append(clone[0])
        };

        const cloneAttachFnTwo = clone => {
          element[0].querySelector('.two').append(clone[0])
        }

        transcludeFn(cloneAttachFnOne, null, 'one');
        transcludeFn(cloneAttachFnTwo, null, 'two');
      }
    }
  });