aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2010-04-05 21:26:52 -0700
committerMisko Hevery2010-04-05 21:26:52 -0700
commite6460685869e16b5016de975fd0ba15a7e436951 (patch)
treebdf55503a5efd7e1922b73ab8ea0ac23c4137cf9
parent2107eafcde390eebbf59e829194626c488de9e29 (diff)
downloadangular.js-e6460685869e16b5016de975fd0ba15a7e436951.tar.bz2
added ng-controller directive
-rw-r--r--src/Scope.js14
-rw-r--r--src/directives.js11
-rw-r--r--src/jqLite.js3
-rw-r--r--test/directivesSpec.js15
4 files changed, 40 insertions, 3 deletions
diff --git a/src/Scope.js b/src/Scope.js
index 562dfbd8..b41f7436 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -1,4 +1,4 @@
-function getter(instance, path) {
+function getter(instance, path, unboundFn) {
if (!path) return instance;
var element = path.split('.');
var key;
@@ -22,7 +22,7 @@ function getter(instance, path) {
}
}
}
- if (typeof instance === 'function' && !instance['$$factory']) {
+ if (!unboundFn && isFunction(instance) && !instance['$$factory']) {
return bind(lastInstance, instance);
}
return instance;
@@ -146,7 +146,17 @@ function createScope(parent, services, existing) {
fn: expressionCompile(expr),
handler: exceptionHandler
});
+ },
+
+ $become: function(Class) {
+ // remove existing
+ foreach(behavior, function(value, key){ delete behavior[key]; });
+ foreach((Class || noop).prototype, function(fn, name){
+ behavior[name] = bind(instance, fn);
+ });
+ (Class || noop).call(instance);
}
+
});
if (!parent.$root) {
diff --git a/src/directives.js b/src/directives.js
index 4f2916da..d1b1dba3 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -4,6 +4,17 @@ angularDirective("ng-init", function(expression){
};
});
+angularDirective("ng-controller", function(expression){
+ return function(element){
+ var controller = getter(window, expression, true) || getter(this, expression, true);
+ if (!controller)
+ throw "Can not find '"+expression+"' controller.";
+ if (!isFunction(controller))
+ throw "Reference '"+expression+"' is not a class.";
+ this.$become(controller);
+ };
+});
+
angularDirective("ng-eval", function(expression){
return function(element){
this.$onEval(expression, element);
diff --git a/src/jqLite.js b/src/jqLite.js
index 331db68d..9aa4f2c7 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -115,7 +115,8 @@ JQLite.prototype = {
remove: function() {
this.dealoc();
- this[0].parentNode.removeChild(this[0]);
+ var parentNode = this[0].parentNode;
+ if (parentNode) parentNode.removeChild(this[0]);
},
removeAttr: function(name) {
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 06a3a2dd..0a7e3c18 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -156,4 +156,19 @@ describe("directives", function(){
scope.$eval();
expect(element.css('display')).toEqual('');
});
+
+ it('should ng-controller', function(){
+ window.Greeter = function(){
+ this.greeting = 'hello';
+ };
+ window.Greeter.prototype = {
+ greet: function(name) {
+ return this.greeting + ' ' + name;
+ }
+ };
+ var scope = compile('<div ng-controller="Greeter"></div>');
+ expect(scope.greeting).toEqual('hello');
+ expect(scope.greet('misko')).toEqual('hello misko');
+ delete window.Greeter;
+ });
});