diff --git a/README.md b/README.md index 678da86..1630cfc 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,9 @@ ngTranscludeMod ============== A modification adding features to Angular's ngTransclude + +This branch allows for angular 1.5 multi-slot-transclusion + +Here is a plunker displaying all the different types of transclusion options + +http://plnkr.co/edit/5XGBEX0muH9CSijMfWsH?p=preview diff --git a/ngTranscludeMod.js b/ngTranscludeMod.js index 5f1f9bf..2cb1102 100644 --- a/ngTranscludeMod.js +++ b/ngTranscludeMod.js @@ -1,51 +1,72 @@ -angular.module( 'ngTranscludeMod', [] ) +angular.module('ngTranscludeMod', []) + .config([ + '$provide', function ($provide) { + $provide.decorator('ngTranscludeDirective', [ + '$delegate', function ($delegate) { + // Remove the original directive + $delegate.shift(); + return $delegate; + } + ]); + } + ]) + .directive('ngTransclude', function () { + return { + restrict: 'EAC', + replace: true, + link: function ($scope, $element, $attrs, controller, $transclude) { -.config(['$provide', function($provide) { - $provide.decorator('ngTranscludeDirective', ['$delegate', function($delegate) { - // Remove the original directive - $delegate.shift(); - return $delegate; - }]); -}]) + var types = ['child', 'parent', 'sibling']; + var iScopeType = types[types.indexOf($attrs.ngTransclude)] || undefined; -.directive( 'ngTransclude', function() { - return { - restrict: 'EAC', - link: function( $scope, $element, $attrs, controller, $transclude ) { - if (!$transclude) { - throw minErr('ngTransclude')('orphan', + if ($attrs.ngTransclude === $attrs.$attr.ngTransclude || iScopeType) { + // If the attribute is of the form: `ng-transclude="ng-transclude"` + // then treat it like the default + $attrs.ngTransclude = ''; + } + + if (!$transclude) { + throw minErr('ngTransclude')('orphan', 'Illegal use of ngTransclude directive in the template! ' + 'No parent directive that requires a transclusion found. ' + 'Element: {0}', - startingTag($element) ); - } + startingTag($element)); + } - var iScopeType = $attrs['ngTransclude'] || 'sibling'; - switch ( iScopeType ) { - case 'sibling': - $transclude( function( clone ) { - $element.empty(); - $element.append( clone ); - }); - break; - case 'parent': - $transclude( $scope, function( clone ) { - $element.empty(); - $element.append( clone ); - }); - break; - case 'child': - var iChildScope = $scope.$new(); - $transclude( iChildScope, function( clone ) { - $element.empty(); - $element.append( clone ); - $element.on( '$destroy', function() { - iChildScope.$destroy(); - }); - }); - break; + //default function for transclude (same as 'sibling') + var ngTranscludeScope; + // If there is no slot name defined or the slot name is not optional + // then transclude the slot + var ngTranscludeSlotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot; + var ngTranscludeCloneAttachFn = function (clone) { + if (clone.length) { + $element.empty(); + $element.append(clone); } + }; + + switch (iScopeType) { + case 'parent': + ngTranscludeScope = $scope; + break; + case 'child': + ngTranscludeScope = $scope.$new(); + ngTranscludeCloneAttachFn = function (clone) { + $element.empty(); + $element.append(clone); + $element.on('$destroy', function () { + ngTranscludeScope.$destroy(); + }); + }; + break; + } + //Scope cant be null + if (ngTranscludeScope) { + $transclude(ngTranscludeScope, ngTranscludeCloneAttachFn, null, ngTranscludeSlotName); + } else { + $transclude(ngTranscludeCloneAttachFn, null, ngTranscludeSlotName); + } } - } -}); \ No newline at end of file + }; + });