From a9a0e27e94bcccc5b8e75317d58771524227078e Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Mon, 12 Feb 2018 17:50:23 +0200 Subject: [PATCH] fix(upgrade): fix empty transclusion content with AngularJS@>=1.5.8 (#22167) The function provided by `ngUpgrade` as `parentBoundTranscludeFn` when upgrading a component with transclusion, will break in AngularJS v1.5.8+ if no transclusion content is provided. The reason is that AngularJS will try to destroy the transclusion scope (which would not be needed any more). But since the transcluded content comes from Angular, not AngularJS, there is no transclusion scope to destroy. This commit fixes it by providing a dummy scope object with a no-op `$destroy()` method. Fixes #22175 PR Close #22167 --- packages/upgrade/src/common/upgrade_helper.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/upgrade/src/common/upgrade_helper.ts b/packages/upgrade/src/common/upgrade_helper.ts index 0b9c6a8022..c31ba7eb1c 100644 --- a/packages/upgrade/src/common/upgrade_helper.ts +++ b/packages/upgrade/src/common/upgrade_helper.ts @@ -122,9 +122,15 @@ export class UpgradeHelper { prepareTransclusion(): angular.ILinkFn|undefined { const transclude = this.directive.transclude; const contentChildNodes = this.extractChildNodes(); + const attachChildrenFn: angular.ILinkFn = (scope, cloneAttachFn) => { + // Since AngularJS v1.5.8, `cloneAttachFn` will try to destroy the transclusion scope if + // `$template` is empty. Since the transcluded content comes from Angular, not AngularJS, + // there will be no transclusion scope here. + // Provide a dummy `scope.$destroy()` method to prevent `cloneAttachFn` from throwing. + scope = scope || {$destroy: () => undefined}; + return cloneAttachFn !($template, scope); + }; let $template = contentChildNodes; - let attachChildrenFn: angular.ILinkFn|undefined = (scope, cloneAttach) => - cloneAttach !($template, scope); if (transclude) { const slots = Object.create(null);