mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
change ng:controller to create new scope hence allow nesting
This commit is contained in:
parent
c30807d141
commit
772e32c220
3 changed files with 56 additions and 23 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)();
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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(){
|
||||
|
|
|
|||
Loading…
Reference in a new issue