From 5a1a6b86a8dbcd8aa4fe9c59fad8d005eead686c Mon Sep 17 00:00:00 2001 From: jankuca Date: Wed, 25 Sep 2013 16:37:59 -0700 Subject: [PATCH] fix(ngTransclude): detect ngTranslude usage without a transclusion directive Closes #3759 --- docs/content/error/ngTransclude/orphan.ngdoc | 12 ++++++++++++ src/ng/directive/ngTransclude.js | 10 +++++++++- test/ng/compileSpec.js | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/content/error/ngTransclude/orphan.ngdoc diff --git a/docs/content/error/ngTransclude/orphan.ngdoc b/docs/content/error/ngTransclude/orphan.ngdoc new file mode 100644 index 000000000000..5ac254329a7c --- /dev/null +++ b/docs/content/error/ngTransclude/orphan.ngdoc @@ -0,0 +1,12 @@ +@ngdoc error +@name ngTransclude:orphan +@fullName Orphan ngTransclude Directive +@description + +Occurs when an `ngTransclude` occurs without a transcluded ancesstor element. + +This error often occurs when you have forgotten to set `transclude: true` in some directive definition, and then used `ngTranslude` in the driective's template. + +To resolve, either remove the offending `ngTransclude` or check that `transclude: true` is included in the intended directive definition. + +Consult the API documentation for {@link guide/directive writing directives} to learn more. diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js index d7c9cd44444c..490ea21f2587 100644 --- a/src/ng/directive/ngTransclude.js +++ b/src/ng/directive/ngTransclude.js @@ -52,7 +52,15 @@ * */ var ngTranscludeDirective = ngDirective({ - controller: ['$transclude', function($transclude) { + controller: ['$element', '$transclude', function($element, $transclude) { + 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)); + } + // remember the transclusion fn but call it during linking so that we don't process transclusion before directives on // the parent element even when the transclusion replaces the current element. (we can't use priority here because // that applies only to compile fns and not controllers diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index c6ba5480cd64..580d51c3b87b 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -2834,6 +2834,22 @@ describe('$compile', function() { }); + it('should throw on an ng-translude element inside no transclusion directive', function() { + inject(function ($rootScope, $compile) { + // we need to do this because different browsers print empty attributres differently + try { + $compile('
')($rootScope); + } catch(e) { + expect(e.message).toMatch(new RegExp( + '^\\\[ngTransclude:orphan\\\] ' + + 'Illegal use of ngTransclude directive in the template! ' + + 'No parent directive that requires a transclusion found\. ' + + 'Element: