diff options
| author | Misko Hevery | 2010-10-06 17:01:41 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2010-10-08 16:23:26 -0700 | 
| commit | 772e32c220193f026c6f4b4674b44ab915e6f0f0 (patch) | |
| tree | 83620adb4d35c0ce63d4cf4d1a92e30a1d59eabd | |
| parent | c30807d1413ea9942bcb065a02997082bf4291aa (diff) | |
| download | angular.js-772e32c220193f026c6f4b4674b44ab915e6f0f0.tar.bz2 | |
change ng:controller to create new scope hence allow nesting
| -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(){  | 
