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 b140bcc57488..15f992c96274 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;