From 9590bcf0620cd507a7795c55f9a6f4a48bfedbc1 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 Closes: #13543 --- 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 2b844b84ba3d..7e3279b83ecb 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 a9725f8769ee..1625e31d64de 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;