angular.js/src/directives.js

186 lines
5.2 KiB
JavaScript
Raw Normal View History

2010-03-22 20:58:04 +00:00
angularDirective("ng-init", function(expression){
2010-03-26 05:03:11 +00:00
return function(element){
this.$tryEval(expression, element);
2010-03-16 17:30:26 +00:00
};
});
2010-03-22 20:58:04 +00:00
angularDirective("ng-eval", function(expression){
2010-03-26 05:03:11 +00:00
return function(element){
this.$onEval(expression, element);
};
2010-03-16 17:30:26 +00:00
});
2010-03-22 22:46:34 +00:00
angularDirective("ng-bind", function(expression){
2010-03-22 20:58:04 +00:00
return function(element) {
2010-03-16 17:30:26 +00:00
this.$watch(expression, function(value){
2010-03-22 20:58:04 +00:00
element.text(value);
2010-03-26 05:03:11 +00:00
}, element);
2010-03-16 17:30:26 +00:00
};
});
2010-03-23 21:57:11 +00:00
var bindTemplateCache = {};
function compileBindTemplate(template){
var fn = bindTemplateCache[template];
if (!fn) {
var bindings = [];
foreach(parseBindings(template), function(text){
var exp = binding(text);
bindings.push(exp ? function(){
return this.$eval(exp);
} : function(){
return text;
});
});
bindTemplateCache[template] = fn = function(){
var parts = [], self = this;
foreach(bindings, function(fn){
parts.push(fn.call(self));
});
return parts.join('');
};
}
return fn;
};
angularDirective("ng-bind-template", function(expression){
var templateFn = compileBindTemplate(expression);
return function(element) {
var lastValue;
2010-03-26 05:03:11 +00:00
this.$onEval(function() {
2010-03-23 21:57:11 +00:00
var value = templateFn.call(this);
if (value != lastValue) {
element.text(value);
lastValue = value;
}
2010-03-26 05:03:11 +00:00
}, element);
2010-03-23 21:57:11 +00:00
};
});
2010-03-22 22:46:34 +00:00
angularDirective("ng-bind-attr", function(expression){
2010-03-22 20:58:04 +00:00
return function(element){
2010-03-26 05:03:11 +00:00
this.$onEval(function(){
2010-03-23 21:57:11 +00:00
foreach(this.$eval(expression), function(value, key){
element.attr(key, compileBindTemplate(value).call(this));
}, this);
2010-03-26 05:03:11 +00:00
}, element);
2010-03-16 17:30:26 +00:00
};
});
2010-03-22 22:46:34 +00:00
angularDirective("ng-non-bindable", function(){
2010-03-22 20:58:04 +00:00
this.descend(false);
});
2010-03-22 22:46:34 +00:00
angularDirective("ng-repeat", function(expression, element){
2010-03-26 05:03:11 +00:00
element.removeAttr('ng-repeat');
element.replaceWith(this.comment("ng-repeat: " + expression));
var template = this.compile(element);
return function(reference){
var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
lhs, rhs, valueIdent, keyIdent;
if (! match) {
throw "Expected ng-repeat in form of 'item in collection' but got '" +
2010-03-22 22:46:34 +00:00
expression + "'.";
2010-03-26 05:03:11 +00:00
}
lhs = match[1];
rhs = match[2];
match = lhs.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);
if (!match) {
throw "'item' in 'item in collection' should be identifier or (key, value) but got '" +
2010-03-22 22:46:34 +00:00
keyValue + "'.";
2010-03-26 05:03:11 +00:00
}
valueIdent = match[3] || match[1];
keyIdent = match[2];
2010-03-22 22:46:34 +00:00
2010-03-26 05:03:11 +00:00
var children = [], currentScope = this;
this.$onEval(function(){
2010-03-22 20:58:04 +00:00
var index = 0, childCount = children.length, childScope, lastElement = reference;
2010-03-26 05:03:11 +00:00
foreach(this.$tryEval(rhs, reference), function(value, key){
2010-03-22 20:58:04 +00:00
if (index < childCount) {
// reuse existing child
childScope = children[index];
} else {
// grow children
childScope = template(element.clone(), currentScope);
2010-03-26 05:03:11 +00:00
lastElement.after(childScope.$element);
childScope.$index = index;
childScope.$element.attr('ng-index', index);
childScope.$init();
2010-03-22 20:58:04 +00:00
children.push(childScope);
}
2010-03-26 05:03:11 +00:00
childScope[valueIdent] = value;
if (keyIdent) childScope[keyIdent] = key;
childScope.$eval();
lastElement = childScope.$element;
2010-03-22 20:58:04 +00:00
index ++;
2010-03-16 17:30:26 +00:00
});
2010-03-22 20:58:04 +00:00
// shrink children
while(children.length > index) {
2010-03-26 05:03:11 +00:00
children.pop().$element.remove();
2010-03-22 20:58:04 +00:00
}
2010-03-26 05:03:11 +00:00
}, reference);
2010-03-16 17:30:26 +00:00
};
2010-03-22 20:58:04 +00:00
}, {exclusive: true});
angularDirective("ng-action", function(expression, element){
2010-03-26 05:03:11 +00:00
return function(element){
var self = this;
element.click(function(){
2010-03-26 05:03:11 +00:00
self.$tryEval(expression, element);
});
};
});
2010-03-22 23:07:42 +00:00
angularDirective("ng-watch", function(expression, element){
var match = expression.match(/^([^.]*):(.*)$/);
2010-03-26 05:03:11 +00:00
return function(element){
if (!match) {
throw "Expecting watch expression 'ident_to_watch: watch_statement' got '"
+ expression + "'";
}
this.$watch(match[1], match[2], element);
2010-03-22 23:07:42 +00:00
};
});
2010-03-23 04:29:57 +00:00
function ngClass(selector) {
return function(expression, element){
var existing = element[0].className + ' ';
return function(element){
2010-03-26 05:03:11 +00:00
this.$onEval(function(){
var value = this.$eval(expression);
2010-03-23 04:29:57 +00:00
if (selector(this.$index)) {
if (isArray(value)) value = value.join(' ');
element[0].className = (existing + value).replace(/\s\s+/g, ' ');
}
2010-03-26 05:03:11 +00:00
}, element);
2010-03-23 04:29:57 +00:00
};
};
}
angularDirective("ng-class", ngClass(function(){return true;}));
angularDirective("ng-class-odd", ngClass(function(i){return i % 2 == 1;}));
angularDirective("ng-class-even", ngClass(function(i){return i % 2 == 0;}));
2010-03-22 20:58:04 +00:00
2010-03-23 04:29:57 +00:00
angularDirective("ng-show", function(expression, element){
return function(element){
2010-03-26 05:03:11 +00:00
this.$onEval(function(){
element.css('display', toBoolean(this.$eval(expression)) ? '' : 'none');
}, element);
2010-03-23 04:29:57 +00:00
};
});
angularDirective("ng-hide", function(expression, element){
return function(element){
2010-03-26 05:03:11 +00:00
this.$onEval(function(){
element.css('display', toBoolean(this.$eval(expression)) ? 'none' : '');
}, element);
2010-03-23 04:29:57 +00:00
};
});
2010-03-16 17:30:26 +00:00
2010-03-23 21:57:11 +00:00
angularDirective("ng-style", function(expression, element){
return function(element){
2010-03-26 05:03:11 +00:00
this.$onEval(function(){
element.css(this.$eval(expression));
}, element);
2010-03-23 21:57:11 +00:00
};
});
2010-03-16 20:50:47 +00:00