mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-09 15:24:43 +00:00
rudementary event bind and trigger for jqlite
This commit is contained in:
parent
7c87c17d08
commit
a822708674
4 changed files with 111 additions and 11 deletions
|
|
@ -50,7 +50,39 @@ Template.prototype = {
|
||||||
//JQLite
|
//JQLite
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
|
var jqCache = {};
|
||||||
|
var jqName = 'ng-' + new Date().getTime();
|
||||||
|
var jqId = 1;
|
||||||
|
function jqNextId() { return jqId++; }
|
||||||
|
|
||||||
|
var addEventListener = window.document.attachEvent ?
|
||||||
|
function(element, type, fn) {
|
||||||
|
element.attachEvent('on' + type, fn);
|
||||||
|
} : function(element, type, fn) {
|
||||||
|
element.addEventListener(type, fn, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
var removeEventListener = window.document.detachEvent ?
|
||||||
|
function(element, type, fn) {
|
||||||
|
element.detachEvent('on' + type, fn);
|
||||||
|
} : function(element, type, fn) {
|
||||||
|
element.removeEventListener(type, fn, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
function jqClearData(element) {
|
||||||
|
var cacheId = element[jqName],
|
||||||
|
cache = jqCache[cacheId];
|
||||||
|
if (cache) {
|
||||||
|
foreach(cache.bind || {}, function(fn, type){
|
||||||
|
removeEventListener(element, type, fn);
|
||||||
|
});
|
||||||
|
delete jqCache[cacheId];
|
||||||
|
delete element[jqName];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function JQLite(element) {
|
function JQLite(element) {
|
||||||
|
//todo: change to this[0];
|
||||||
this.element = element;
|
this.element = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,6 +96,67 @@ function jqLite(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
JQLite.prototype = {
|
JQLite.prototype = {
|
||||||
|
data: function(key, value) {
|
||||||
|
var element = this.element,
|
||||||
|
cacheId = element[jqName],
|
||||||
|
cache = jqCache[cacheId || -1];
|
||||||
|
if (isDefined(value)) {
|
||||||
|
if (!cache) {
|
||||||
|
element[jqName] = cacheId = jqNextId();
|
||||||
|
cache = jqCache[cacheId] = {};
|
||||||
|
}
|
||||||
|
cache[key] = value;
|
||||||
|
} else {
|
||||||
|
return cache ? cache[key] : null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeData: function(){
|
||||||
|
jqClearData(this.element);
|
||||||
|
},
|
||||||
|
|
||||||
|
dealoc: function(){
|
||||||
|
(function dealoc(element){
|
||||||
|
jqClearData(element);
|
||||||
|
for ( var i = 0, children = element.childNodes; i < children.length; i++) {
|
||||||
|
dealoc(children[0]);
|
||||||
|
}
|
||||||
|
})(this.element);
|
||||||
|
},
|
||||||
|
|
||||||
|
bind: function(type, fn){
|
||||||
|
var element = this.element,
|
||||||
|
bind = this.data('bind'),
|
||||||
|
eventHandler;
|
||||||
|
if (!bind) this.data('bind', bind = {});
|
||||||
|
eventHandler = bind[type];
|
||||||
|
if (!eventHandler) {
|
||||||
|
bind[type] = eventHandler = function() {
|
||||||
|
var self = this;
|
||||||
|
foreach(eventHandler.fns, function(fn){
|
||||||
|
fn.apply(self, arguments);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
eventHandler.fns = [];
|
||||||
|
addEventListener(element, type, eventHandler);
|
||||||
|
}
|
||||||
|
eventHandler.fns.push(fn);
|
||||||
|
},
|
||||||
|
|
||||||
|
trigger: function(type) {
|
||||||
|
var cache = this.data('bind');
|
||||||
|
if (cache) {
|
||||||
|
(cache[type] || noop)();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
click: function(fn) {
|
||||||
|
if (fn)
|
||||||
|
this.bind('click', fn);
|
||||||
|
else
|
||||||
|
this.trigger('click');
|
||||||
|
},
|
||||||
|
|
||||||
eachTextNode: function(fn){
|
eachTextNode: function(fn){
|
||||||
var i, chldNodes = this.element.childNodes || [], size = chldNodes.length, chld;
|
var i, chldNodes = this.element.childNodes || [], size = chldNodes.length, chld;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
|
|
@ -96,6 +189,7 @@ JQLite.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function() {
|
remove: function() {
|
||||||
|
this.dealoc();
|
||||||
this.element.parentNode.removeChild(this.element);
|
this.element.parentNode.removeChild(this.element);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
19
src/Scope.js
19
src/Scope.js
|
|
@ -73,7 +73,7 @@ Scope.prototype = {
|
||||||
// todo: this is a hack, which will need to be cleaned up.
|
// todo: this is a hack, which will need to be cleaned up.
|
||||||
var self = this,
|
var self = this,
|
||||||
listenFn = listener || noop,
|
listenFn = listener || noop,
|
||||||
expr = bind(self, self.compile(fn), {scope: self, self: self.state});
|
expr = self.compile(fn);
|
||||||
this.evals.push(function(){
|
this.evals.push(function(){
|
||||||
self.apply(listenFn, expr());
|
self.apply(listenFn, expr());
|
||||||
});
|
});
|
||||||
|
|
@ -117,23 +117,24 @@ Scope.prototype = {
|
||||||
|
|
||||||
compile: function(exp) {
|
compile: function(exp) {
|
||||||
if (isFunction(exp)) return exp;
|
if (isFunction(exp)) return exp;
|
||||||
var expFn = Scope.expressionCache[exp];
|
var expFn = Scope.expressionCache[exp], self = this;
|
||||||
if (!expFn) {
|
if (!expFn) {
|
||||||
var parser = new Parser(exp);
|
var parser = new Parser(exp);
|
||||||
expFn = parser.statements();
|
expFn = parser.statements();
|
||||||
parser.assertAllConsumed();
|
parser.assertAllConsumed();
|
||||||
Scope.expressionCache[exp] = expFn;
|
Scope.expressionCache[exp] = expFn;
|
||||||
}
|
}
|
||||||
return expFn;
|
return function(context){
|
||||||
|
context = context || {};
|
||||||
|
context.self = self.state;
|
||||||
|
context.scope = self;
|
||||||
|
return expFn.call(self, context);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
eval: function(expressionText, context) {
|
eval: function(expressionText, context) {
|
||||||
// log('Scope.eval', expressionText);
|
// log('Scope.eval', expressionText);
|
||||||
var expression = this.compile(expressionText);
|
return this.compile(expressionText)(context);
|
||||||
context = context || {};
|
|
||||||
context.scope = this;
|
|
||||||
context.self = this.state;
|
|
||||||
return expression(context);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//TODO: Refactor. This function needs to be an execution closure for widgets
|
//TODO: Refactor. This function needs to be an execution closure for widgets
|
||||||
|
|
@ -209,7 +210,7 @@ Scope.prototype = {
|
||||||
addWatchListener: function(watchExpression, listener) {
|
addWatchListener: function(watchExpression, listener) {
|
||||||
// TODO: clean me up!
|
// TODO: clean me up!
|
||||||
if (!isFunction(listener)) {
|
if (!isFunction(listener)) {
|
||||||
listener = bind(this, this.compile(listener), {scope: this, self: this.state});
|
listener = this.compile(listener);
|
||||||
}
|
}
|
||||||
var watcher = this.watchListeners[watchExpression];
|
var watcher = this.watchListeners[watchExpression];
|
||||||
if (!watcher) {
|
if (!watcher) {
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ angularDirective("ng-repeat", function(expression, element){
|
||||||
angularDirective("ng-action", function(expression, element){
|
angularDirective("ng-action", function(expression, element){
|
||||||
return function(){
|
return function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
jQuery(element.element).click(function(){
|
element.click(function(){
|
||||||
self.$eval(expression);
|
self.$eval(expression);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ describe("directives", function(){
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(function(){
|
||||||
|
element.remove();
|
||||||
|
expect(_(jqCache).size()).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
it("should ng-init", function() {
|
it("should ng-init", function() {
|
||||||
var scope = compile('<div ng-init="a=123"></div>');
|
var scope = compile('<div ng-init="a=123"></div>');
|
||||||
expect(scope.get('a')).toEqual(123);
|
expect(scope.get('a')).toEqual(123);
|
||||||
|
|
@ -100,7 +105,7 @@ describe("directives", function(){
|
||||||
scope.updateView();
|
scope.updateView();
|
||||||
expect(scope.get('clicked')).toBeFalsy();
|
expect(scope.get('clicked')).toBeFalsy();
|
||||||
|
|
||||||
jQuery(element.element).click();
|
element.click();
|
||||||
expect(scope.get('clicked')).toEqual(true);
|
expect(scope.get('clicked')).toEqual(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue