Fix for getting into recursive $eval on scope. Close #59

It sort of worked since the browser would throw stack too deep
exception and the angular would then print the error to console.
So as long as you did not have console open you would not notice
this as an error.
This commit is contained in:
Misko Hevery 2010-10-23 13:42:11 -07:00
parent 6ddcf91861
commit d74ef497de
5 changed files with 30 additions and 2 deletions

View file

@ -2,7 +2,6 @@
<html xmlns:ng="http://angularjs.org">
<head>
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
</script>
</head>
<body ng:init="$window.$root = this; data = [{foo: 'foo'},{bar: 'bar'}]">
<p>This is a demo of a potential bug in angular.</p>

View file

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html xmlns:ng="http://angularjs.org">
<head>
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
</head>
<body ng:init="$window.$root = this; data = [{foo: 'foo'},{bar: 'bar'}]">
<ng:include src="'ng_include_this.partial'" scope="this"/>
</body>
</html>

View file

@ -0,0 +1 @@
included HTML. eval count: {{c=c+1}}

View file

@ -256,11 +256,19 @@ angularWidget('ng:include', function(element){
return extend(function(xhr, element){
var scope = this, childScope;
var changeCounter = 0;
var preventRecursion = false;
function incrementChange(){ changeCounter++;}
this.$watch(srcExp, incrementChange);
this.$watch(scopeExp, incrementChange);
scope.$onEval(function(){
if (childScope) childScope.$eval();
if (childScope && !preventRecursion) {
preventRecursion = true;
try {
childScope.$eval();
} finally {
preventRecursion = false;
}
}
});
this.$watch(function(){return changeCounter;}, function(){
var src = this.$eval(srcExp),

View file

@ -497,6 +497,17 @@ describe("widget", function(){
expect(element.text()).toEqual('');
});
it('should allow this for scope', function(){
var element = jqLite('<ng:include src="url" scope="this"></ng:include>');
var scope = angular.compile(element);
scope.url = 'myUrl';
scope.$inject('$xhr.cache').data.myUrl = {value:'{{c=c+1}}'};
scope.$init();
// This should not be 4, but to fix this properly
// we need to have real events on the scopes.
expect(element.text()).toEqual('4');
});
});
describe('a', function() {