From f927a1f3ea1ac3ef5de5819c6d235181df9b5ee5 Mon Sep 17 00:00:00 2001 From: Alexander Zagumennikov Date: Tue, 15 Dec 2015 14:01:35 +0400 Subject: [PATCH] fix(ngInclude): do not compile template if original scope is destroyed With slow internet connection scope may be destroyed before template is loaded. Previously in this case ngInclude compiled template that leaded to memory leaks and errors in some cases. Closes #13515 --- src/ng/directive/ngInclude.js | 4 ++++ test/ng/directive/ngIncludeSpec.js | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index b140bcc5748..15f992c9627 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -232,6 +232,8 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', //set the 2nd param to true to ignore the template request error so that the inner //contents and scope can be cleaned up. $templateRequest(src, true).then(function(response) { + if (scope.$$destroyed) return; + if (thisChangeId !== changeCounter) return; var newScope = scope.$new(); ctrl.template = response; @@ -253,6 +255,8 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', currentScope.$emit('$includeContentLoaded', src); scope.$eval(onloadExp); }, function() { + if (scope.$$destroyed) return; + if (thisChangeId === changeCounter) { cleanupLastIncludeContent(); scope.$emit('$includeContentError', src); diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index a9725f8769e..1625e31d64d 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -398,6 +398,26 @@ describe('ngInclude', function() { }); + it('should not compile template if original scope is destroyed', function() { + module(function($provide) { + $provide.decorator('$compile', function($delegate) { + return jasmine.createSpy('$compile').andCallFake($delegate); + }); + }); + inject(function($rootScope, $httpBackend, $compile) { + $httpBackend.when('GET', 'url').respond('template text'); + $rootScope.show = true; + element = $compile('
')($rootScope); + $rootScope.$digest(); + $rootScope.show = false; + $rootScope.$digest(); + $compile.reset(); + $httpBackend.flush(); + expect($compile).not.toHaveBeenCalled(); + }); + }); + + describe('autoscroll', function() { var autoScrollSpy;