aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Compiler.js27
-rw-r--r--src/directives.js2
-rw-r--r--test/directivesSpec.js50
3 files changed, 56 insertions, 23 deletions
diff --git a/src/Compiler.js b/src/Compiler.js
index 48638bc3..0c80d3fc 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -9,40 +9,42 @@ function Template(priority) {
this.children = [];
this.inits = [];
this.priority = priority;
+ this.newScope = false;
}
Template.prototype = {
init: function(element, scope) {
var inits = {};
- this.collectInits(element, inits);
+ this.collectInits(element, inits, scope);
foreachSorted(inits, function(queue){
- foreach(queue, function(fn){
- fn(scope);
- });
+ foreach(queue, function(fn) {fn();});
});
},
- collectInits: function(element, inits) {
- var queue = inits[this.priority];
+ collectInits: function(element, inits, scope) {
+ var queue = inits[this.priority], childScope = scope;
if (!queue) {
inits[this.priority] = queue = [];
}
element = jqLite(element);
+ if (this.newScope) {
+ childScope = createScope(scope);
+ scope.$onEval(childScope.$eval);
+ }
foreach(this.inits, function(fn) {
- queue.push(function(scope) {
- scope.$tryEval(function(){
- return fn.call(scope, element);
+ queue.push(function() {
+ childScope.$tryEval(function(){
+ return fn.call(childScope, element);
}, element);
});
});
-
var i,
childNodes = element[0].childNodes,
children = this.children,
paths = this.paths,
length = paths.length;
for (i = 0; i < length; i++) {
- children[i].collectInits(childNodes[paths[i]], inits);
+ children[i].collectInits(childNodes[paths[i]], inits, childScope);
}
},
@@ -121,7 +123,8 @@ Compiler.prototype = {
element:function(type) {return jqLite(document.createElement(type));},
text:function(text) {return jqLite(document.createTextNode(text));},
descend: function(value){ if(isDefined(value)) descend = value; return descend;},
- directives: function(value){ if(isDefined(value)) directives = value; return directives;}
+ directives: function(value){ if(isDefined(value)) directives = value; return directives;},
+ scope: function(value){ if(isDefined(value)) template.newScope = template.newScope || value ; return template.newScope;}
};
try {
priority = element.attr('ng:eval-order') || priority || 0;
diff --git a/src/directives.js b/src/directives.js
index d2d3bf2c..425685f3 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -5,6 +5,7 @@ angularDirective("ng:init", function(expression){
});
angularDirective("ng:controller", function(expression){
+ this.scope(true);
return function(element){
var controller = getter(window, expression, true) || getter(this, expression, true);
if (!controller)
@@ -12,7 +13,6 @@ angularDirective("ng:controller", function(expression){
if (!isFunction(controller))
throw "Reference '"+expression+"' is not a class.";
this.$become(controller);
- (this.init || noop)();
};
});
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 10400ead..42a4879a 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -254,23 +254,53 @@ describe("directives", function(){
});
describe('ng:controller', function(){
- it('should bind', function(){
- window.Greeter = function(){
+
+ var temp;
+
+ beforeEach(function(){
+ temp = window.temp = {};
+ temp.Greeter = function(){
+ this.$root.greeter = this;
this.greeting = 'hello';
+ this.suffix = '!';
};
- window.Greeter.prototype = {
- init: function(){
- this.suffix = '!';
- },
+ temp.Greeter.prototype = {
greet: function(name) {
return this.greeting + ' ' + name + this.suffix;
}
};
- var scope = compile('<div ng:controller="Greeter"></div>');
- expect(scope.greeting).toEqual('hello');
- expect(scope.greet('misko')).toEqual('hello misko!');
- window.Greeter = undefined;
});
+
+ afterEach(function(){
+ window.temp = undefined;
+ });
+
+ it('should bind', function(){
+ var scope = compile('<div ng:controller="temp.Greeter"></div>');
+ expect(scope.greeter.greeting).toEqual('hello');
+ expect(scope.greeter.greet('misko')).toEqual('hello misko!');
+ });
+
+ it('should support nested controllers', function(){
+ temp.ChildGreeter = function() {
+ this.greeting = 'hey';
+ this.$root.childGreeter = this;
+ };
+ temp.ChildGreeter.prototype = {
+ greet: function() {
+ return this.greeting + ' dude' + this.suffix;
+ }
+ };
+ var scope = compile('<div ng:controller="temp.Greeter"><div ng:controller="temp.ChildGreeter">{{greet("misko")}}</div></div>');
+ expect(scope.greeting).not.toBeDefined();
+ expect(scope.greeter.greeting).toEqual('hello');
+ expect(scope.greeter.greet('misko')).toEqual('hello misko!');
+ expect(scope.greeter.greeting).toEqual('hello');
+ expect(scope.childGreeter.greeting).toEqual('hey');
+ expect(scope.childGreeter.$parent.greeting).toEqual('hello');
+ expect(scope.$element.text()).toEqual('hey dude!');
+ });
+
});
it('should eval things according to ng:eval-order', function(){