diff options
| -rw-r--r-- | src/Compiler.js | 27 | ||||
| -rw-r--r-- | src/directives.js | 2 | ||||
| -rw-r--r-- | test/directivesSpec.js | 50 |
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(){ |
