diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js
index 90fd0b40ab40..f1c836f01a0c 100644
--- a/src/ng/directive/ngInclude.js
+++ b/src/ng/directive/ngInclude.js
@@ -15,8 +15,6 @@
*
* @param {string} ng-include|src angular expression evaluating to URL. If the source is a string constant,
* make sure you wrap it in quotes, e.g. `src="'myPartialTemplate.html'"`.
- * @param {Scope=} [scope=new_child_scope] optional expression which evaluates to an
- * instance of angular.module.ng.$rootScope.Scope to set the HTML fragment to.
* @param {string=} onload Expression to evaluate when a new partial is loaded.
*
* @param {string=} autoscroll Whether `ng-include` should call {@link angular.module.ng.$anchorScroll
@@ -78,8 +76,7 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
return {
restrict: 'EA',
compile: function(element, attr) {
- var srcExp = attr.ngInclude || attr.src,
- scopeExp = attr.scope || '',
+ var srcExp = attr.ngInclude || attr.src,
onloadExp = attr.onload || '',
autoScrollExp = attr.autoscroll;
@@ -87,45 +84,40 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
var changeCounter = 0,
childScope;
- function incrementChange() { changeCounter++;}
- scope.$watch(srcExp, incrementChange);
- scope.$watch(function() {
- var includeScope = scope.$eval(scopeExp);
- if (includeScope) return includeScope.$id;
- }, incrementChange);
- scope.$watch(function() {return changeCounter;}, function(newChangeCounter) {
- var src = scope.$eval(srcExp),
- useScope = scope.$eval(scopeExp);
+ var clearContent = function() {
+ if (childScope) {
+ childScope.$destroy();
+ childScope = null;
+ }
+
+ element.html('');
+ };
+
+ scope.$watch(srcExp, function(src) {
+ var thisChangeId = ++changeCounter;
+
+ if (src) {
+ $http.get(src, {cache: $templateCache}).success(function(response) {
+ if (thisChangeId !== changeCounter) return;
- function clearContent() {
- // if this callback is still desired
- if (newChangeCounter === changeCounter) {
if (childScope) childScope.$destroy();
- childScope = null;
- element.html('');
- }
- }
+ childScope = scope.$new();
+
+ element.html(response);
+ $compile(element.contents())(childScope);
+
+ if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+ $anchorScroll();
+ }
- if (src) {
- $http.get(src, {cache: $templateCache}).success(function(response) {
- // if this callback is still desired
- if (newChangeCounter === changeCounter) {
- element.html(response);
- if (childScope) childScope.$destroy();
- childScope = useScope ? useScope : scope.$new();
- $compile(element.contents())(childScope);
- if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
- $anchorScroll();
- }
- scope.$emit('$includeContentLoaded');
- scope.$eval(onloadExp);
- }
- }).error(clearContent);
- } else {
- clearContent();
- }
+ scope.$emit('$includeContentLoaded');
+ scope.$eval(onloadExp);
+ }).error(function() {
+ if (thisChangeId === changeCounter) clearContent();
+ });
+ } else clearContent();
});
};
}
- }
+ };
}];
diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js
index ab63dd02a443..ae9454d6cec5 100644
--- a/test/ng/directive/ngIncludeSpec.js
+++ b/test/ng/directive/ngIncludeSpec.js
@@ -18,11 +18,10 @@ describe('ng-include', function() {
it('should include on external file', inject(putIntoCache('myUrl', '{{name}}'),
function($rootScope, $compile) {
- element = jqLite('');
+ element = jqLite('');
jqLite(document.body).append(element);
element = $compile(element)($rootScope);
- $rootScope.childScope = $rootScope.$new();
- $rootScope.childScope.name = 'misko';
+ $rootScope.name = 'misko';
$rootScope.url = 'myUrl';
$rootScope.$digest();
expect(element.text()).toEqual('misko');
@@ -46,10 +45,9 @@ describe('ng-include', function() {
it('should remove previously included text if a falsy value is bound to src', inject(
putIntoCache('myUrl', '{{name}}'),
function($rootScope, $compile) {
- element = jqLite('');
+ element = jqLite('');
element = $compile(element)($rootScope);
- $rootScope.childScope = $rootScope.$new();
- $rootScope.childScope.name = 'igor';
+ $rootScope.name = 'igor';
$rootScope.url = 'myUrl';
$rootScope.$digest();
@@ -62,23 +60,6 @@ describe('ng-include', function() {
}));
- it('should allow this for scope', inject(putIntoCache('myUrl', '{{"abc"}}'),
- function($rootScope, $compile) {
- element = jqLite('');
- element = $compile(element)($rootScope);
- $rootScope.url = 'myUrl';
- $rootScope.$digest();
-
- // TODO(misko): because we are using scope==this, the eval gets registered
- // during the flush phase and hence does not get called.
- // I don't think passing 'this' makes sense. Does having scope on ng-include makes sense?
- // should we make scope="this" illegal?
- $rootScope.$digest();
-
- expect(element.text()).toEqual('abc');
- }));
-
-
it('should fire $includeContentLoaded event after linking the content', inject(
function($rootScope, $compile, $templateCache) {
var contentLoadedSpy = jasmine.createSpy('content loaded').andCallFake(function() {
@@ -111,20 +92,33 @@ describe('ng-include', function() {
}));
- it('should destroy old scope', inject(putIntoCache('myUrl', 'my partial'),
- function($rootScope, $compile) {
- element = jqLite('');
- element = $compile(element)($rootScope);
+ it('should create child scope and destroy old one', inject(
+ function($rootScope, $compile, $httpBackend) {
+ $httpBackend.whenGET('url1').respond('partial {{$parent.url}}');
+ $httpBackend.whenGET('url2').respond(404);
- expect($rootScope.$$childHead).toBeFalsy();
+ element = $compile('')($rootScope);
+ expect(element.children().scope()).toBeFalsy();
- $rootScope.url = 'myUrl';
+ $rootScope.url = 'url1';
+ $rootScope.$digest();
+ $httpBackend.flush();
+ expect(element.children().scope()).toBeTruthy();
+ expect(element.text()).toBe('partial url1');
+
+ $rootScope.url = 'url2';
+ $rootScope.$digest();
+ $httpBackend.flush();
+ expect(element.children().scope()).toBeFalsy();
+ expect(element.text()).toBe('');
+
+ $rootScope.url = 'url1';
$rootScope.$digest();
- expect($rootScope.$$childHead).toBeTruthy();
+ expect(element.children().scope()).toBeTruthy();
$rootScope.url = null;
$rootScope.$digest();
- expect($rootScope.$$childHead).toBeFalsy();
+ expect(element.children().scope()).toBeFalsy();
}));