mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-09 23:34:42 +00:00
ng-repeat works
This commit is contained in:
parent
84552f7f8a
commit
b4561ff951
4 changed files with 77 additions and 18 deletions
|
|
@ -181,15 +181,32 @@ function escapeAttr(html) {
|
||||||
|
|
||||||
function bind(_this, _function) {
|
function bind(_this, _function) {
|
||||||
var curryArgs = slice.call(arguments, 2, arguments.length);
|
var curryArgs = slice.call(arguments, 2, arguments.length);
|
||||||
if (!_this)
|
|
||||||
throw "Missing this";
|
|
||||||
if (!_.isFunction(_function))
|
|
||||||
throw "Missing function";
|
|
||||||
return function() {
|
return function() {
|
||||||
return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
|
return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bindTry(_this, _function) {
|
||||||
|
var args = arguments,
|
||||||
|
last = args.length - 1,
|
||||||
|
curryArgs = slice.call(args, 2, last),
|
||||||
|
exceptionHandler = args[last];
|
||||||
|
return function() {
|
||||||
|
try {
|
||||||
|
return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
|
||||||
|
} catch (e) {
|
||||||
|
if (e = exceptionHandler(e)) throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorHandlerFor(element) {
|
||||||
|
return function(error){
|
||||||
|
element.attr('ng-error', angular.toJson(error));
|
||||||
|
element.addClass('ng-exception');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function outerHTML(node) {
|
function outerHTML(node) {
|
||||||
var temp = document.createElement('div');
|
var temp = document.createElement('div');
|
||||||
temp.appendChild(node);
|
temp.appendChild(node);
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,20 @@ JQLite.prototype = {
|
||||||
this.element.parentNode.insertBefore(jqLite(element).element, this.element.nextSibling);
|
this.element.parentNode.insertBefore(jqLite(element).element, this.element.nextSibling);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
hasClass: function(selector) {
|
||||||
|
var className = " " + selector + " ";
|
||||||
|
if ( (" " + this.element.className + " ").replace(/[\n\t]/g, " ").indexOf( className ) > -1 ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
addClass: function( selector ) {
|
||||||
|
if (!this.hasClass(selector)) {
|
||||||
|
this.element.className += ' ' + selector;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
attr: function(name, value){
|
attr: function(name, value){
|
||||||
var e = this.element;
|
var e = this.element;
|
||||||
if (isObject(name)) {
|
if (isObject(name)) {
|
||||||
|
|
@ -201,7 +215,7 @@ Compiler.prototype = {
|
||||||
exclusive = true;
|
exclusive = true;
|
||||||
directiveQueue = [];
|
directiveQueue = [];
|
||||||
}
|
}
|
||||||
directiveQueue.push(bind(selfApi, directive, value, element));
|
directiveQueue.push(bindTry(selfApi, directive, value, element, errorHandlerFor(element)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ angularDirective("ng-eval", function(expression){
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
angular.directive("ng-bind", function(expression){
|
angularDirective("ng-bind", function(expression){
|
||||||
return function(element) {
|
return function(element) {
|
||||||
this.$watch(expression, function(value){
|
this.$watch(expression, function(value){
|
||||||
element.text(value);
|
element.text(value);
|
||||||
|
|
@ -18,23 +18,36 @@ angular.directive("ng-bind", function(expression){
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
angular.directive("ng-bind-attr", function(expression){
|
angularDirective("ng-bind-attr", function(expression){
|
||||||
return function(element){
|
return function(element){
|
||||||
this.$watch(expression, bind(element, element.attr));
|
this.$watch(expression, bind(element, element.attr));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
angular.directive("ng-non-bindable", function(){
|
angularDirective("ng-non-bindable", function(){
|
||||||
this.descend(false);
|
this.descend(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
angular.directive("ng-repeat", function(expression, element){
|
angularDirective("ng-repeat", function(expression, element){
|
||||||
var reference = this.reference("ng-repeat: " + expression),
|
var reference = this.reference("ng-repeat: " + expression),
|
||||||
r = element.removeAttr('ng-repeat'),
|
r = element.removeAttr('ng-repeat'),
|
||||||
template = this.compile(element),
|
template = this.compile(element),
|
||||||
path = expression.split(' in '),
|
match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
|
||||||
lhs = path[0],
|
lhs, rhs, valueIdent, keyIdent;
|
||||||
rhs = path[1];
|
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();
|
var parent = element.parent();
|
||||||
element.replaceWith(reference);
|
element.replaceWith(reference);
|
||||||
return function(){
|
return function(){
|
||||||
|
|
@ -42,7 +55,7 @@ angular.directive("ng-repeat", function(expression, element){
|
||||||
currentScope = this;
|
currentScope = this;
|
||||||
this.$addEval(rhs, function(items){
|
this.$addEval(rhs, function(items){
|
||||||
var index = 0, childCount = children.length, childScope, lastElement = reference;
|
var index = 0, childCount = children.length, childScope, lastElement = reference;
|
||||||
foreach(items, function(value, key){
|
foreach(items || [], function(value, key){
|
||||||
if (index < childCount) {
|
if (index < childCount) {
|
||||||
// reuse existing child
|
// reuse existing child
|
||||||
childScope = children[index];
|
childScope = children[index];
|
||||||
|
|
@ -55,7 +68,8 @@ angular.directive("ng-repeat", function(expression, element){
|
||||||
lastElement.after(childScope.element);
|
lastElement.after(childScope.element);
|
||||||
children.push(childScope);
|
children.push(childScope);
|
||||||
}
|
}
|
||||||
childScope.scope.set(lhs, value);
|
childScope.scope.set(valueIdent, value);
|
||||||
|
if (keyIdent) childScope.scope.set(keyIdent, key);
|
||||||
childScope.scope.updateView();
|
childScope.scope.updateView();
|
||||||
lastElement = childScope.element;
|
lastElement = childScope.element;
|
||||||
index ++;
|
index ++;
|
||||||
|
|
@ -86,7 +100,7 @@ angular.directive("ng-repeat", function(expression, element){
|
||||||
//ng-show, ng-hide
|
//ng-show, ng-hide
|
||||||
|
|
||||||
|
|
||||||
angular.directive("action", function(expression, element){
|
angularDirective("action", function(expression, element){
|
||||||
return function(){
|
return function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
jQuery(element).click(function(){
|
jQuery(element).click(function(){
|
||||||
|
|
@ -97,7 +111,7 @@ angular.directive("action", function(expression, element){
|
||||||
|
|
||||||
//ng-watch
|
//ng-watch
|
||||||
// <div ng-watch="$anchor.book: book=Book.get();"/>
|
// <div ng-watch="$anchor.book: book=Book.get();"/>
|
||||||
angular.directive("watch", function(expression, element){
|
angularDirective("watch", function(expression, element){
|
||||||
var watches = {
|
var watches = {
|
||||||
'lhs':'rhs'
|
'lhs':'rhs'
|
||||||
}; // parse
|
}; // parse
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,20 @@ describe("directives", function(){
|
||||||
expect(element.text()).toEqual('brad;');
|
expect(element.text()).toEqual('brad;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ng-repeat over object', function(){});
|
it('should ng-repeat over object', function(){
|
||||||
it('should error on wrong parsing of ng-repeat', function(){});
|
var scope = compile('<ul><li ng-repeat="(key, value) in items" ng-bind="key + \':\' + value + \';\' "></li></ul>');
|
||||||
|
scope.set('items', {misko:'swe', shyam:'set'});
|
||||||
|
scope.updateView();
|
||||||
|
expect(element.text()).toEqual('misko:swe;shyam:set;');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error on wrong parsing of ng-repeat', function(){
|
||||||
|
var scope = compile('<ul><li ng-repeat="i dont parse"></li></ul>');
|
||||||
|
var log = "";
|
||||||
|
element.eachNode(function(li){
|
||||||
|
log += li.attr('ng-error') + ';';
|
||||||
|
log += li.hasClass('ng-exception') + ';';
|
||||||
|
});
|
||||||
|
expect(log).toEqual("\"Expected ng-repeat in form of 'item in collection' but got 'i dont parse'.\";true;");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue