mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-28 04:00:23 +00:00
187 lines
5.1 KiB
JavaScript
187 lines
5.1 KiB
JavaScript
angularDirective("ng-init", function(expression){
|
|
return function(){
|
|
this.$eval(expression);
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-eval", function(expression){
|
|
return function(){
|
|
this.$addEval(expression);
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-bind", function(expression){
|
|
return function(element) {
|
|
this.$watch(expression, function(value){
|
|
element.text(value);
|
|
});
|
|
};
|
|
});
|
|
|
|
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;
|
|
this.$addEval(function() {
|
|
var value = templateFn.call(this);
|
|
if (value != lastValue) {
|
|
element.text(value);
|
|
lastValue = value;
|
|
}
|
|
});
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-bind-attr", function(expression){
|
|
return function(element){
|
|
this.$addEval(function(){
|
|
foreach(this.$eval(expression), function(value, key){
|
|
element.attr(key, compileBindTemplate(value).call(this));
|
|
}, this);
|
|
});
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-non-bindable", function(){
|
|
this.descend(false);
|
|
});
|
|
|
|
angularDirective("ng-repeat", function(expression, element){
|
|
var reference = this.comment("ng-repeat: " + expression),
|
|
r = element.removeAttr('ng-repeat'),
|
|
template = this.compile(element),
|
|
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 '" +
|
|
expression + "'.";
|
|
}
|
|
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 '" +
|
|
keyValue + "'.";
|
|
}
|
|
valueIdent = match[3] || match[1];
|
|
keyIdent = match[2];
|
|
|
|
var parent = element.parent();
|
|
element.replaceWith(reference);
|
|
return function(){
|
|
var children = [],
|
|
currentScope = this;
|
|
this.$addEval(rhs, function(items){
|
|
var index = 0, childCount = children.length, childScope, lastElement = reference;
|
|
foreach(items || [], function(value, key){
|
|
if (index < childCount) {
|
|
// reuse existing child
|
|
childScope = children[index];
|
|
} else {
|
|
// grow children
|
|
childScope = template(element.clone(), currentScope);
|
|
childScope.init();
|
|
childScope.scope.set('$index', index);
|
|
childScope.element.attr('ng-index', index);
|
|
lastElement.after(childScope.element);
|
|
children.push(childScope);
|
|
}
|
|
childScope.scope.set(valueIdent, value);
|
|
if (keyIdent) childScope.scope.set(keyIdent, key);
|
|
childScope.scope.updateView();
|
|
lastElement = childScope.element;
|
|
index ++;
|
|
});
|
|
// shrink children
|
|
while(children.length > index) {
|
|
children.pop().element.remove();
|
|
}
|
|
});
|
|
};
|
|
}, {exclusive: true});
|
|
|
|
angularDirective("ng-action", function(expression, element){
|
|
return function(){
|
|
var self = this;
|
|
element.click(function(){
|
|
self.$eval(expression);
|
|
});
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-watch", function(expression, element){
|
|
var match = expression.match(/^([^.]*):(.*)$/);
|
|
if (!match) {
|
|
throw "Expecting watch expression 'ident_to_watch: watch_statement' got '"
|
|
+ expression + "'";
|
|
}
|
|
return function(){
|
|
this.$watch(match[1], match[2]);
|
|
};
|
|
});
|
|
|
|
function ngClass(selector) {
|
|
return function(expression, element){
|
|
var existing = element[0].className + ' ';
|
|
return function(element){
|
|
this.$addEval(expression, function(value){
|
|
if (selector(this.$index)) {
|
|
if (isArray(value)) value = value.join(' ');
|
|
element[0].className = (existing + value).replace(/\s\s+/g, ' ');
|
|
}
|
|
});
|
|
};
|
|
};
|
|
}
|
|
|
|
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;}));
|
|
|
|
angularDirective("ng-show", function(expression, element){
|
|
return function(element){
|
|
this.$addEval(expression, function(value){
|
|
element.css('display', toBoolean(value) ? '' : 'none');
|
|
});
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-hide", function(expression, element){
|
|
return function(element){
|
|
this.$addEval(expression, function(value){
|
|
element.css('display', toBoolean(value) ? 'none' : '');
|
|
});
|
|
};
|
|
});
|
|
|
|
angularDirective("ng-style", function(expression, element){
|
|
return function(element){
|
|
this.$addEval(expression, function(value){
|
|
element.css(value);
|
|
});
|
|
};
|
|
});
|
|
|