Skip to content

Instantly share code, notes, and snippets.

@akearney
Created March 18, 2014 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akearney/9624142 to your computer and use it in GitHub Desktop.
Save akearney/9624142 to your computer and use it in GitHub Desktop.
const repeat
// WARNING: dont use this with a custom element directive that sets scope
// in the link.
.directive('r77ConstRepeat', function() {
return {
transclude: 'element',
// Priority is same as a normal ng-repeat
priority: 1000,
compile: function(elt, attr, linker) {
return function(scope, iterStartElement, attr) {
// Most of this code is stolen from angular.js for ngRepeat, we just
// don't want to watch
var expression = attr.r77ConstRepeat;
var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
lhs, rhs, valueIdent, keyIdent;
if (! match) {
throw Error("Expected r77ConstRepeat 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 Error("'item' in 'item in collection' should be identifier or (key, value) but got '" +
lhs + "'.");
}
valueIdent = match[3] || match[1];
keyIdent = match[2];
var index, length,
collection = scope.$eval(rhs),
cursor = iterStartElement,
arrayBound,
childScope,
key, value, // key/value of iteration
array;
if (!angular.isArray(collection)) {
// if object, extract keys, sort them and use to determine order of iteration over obj props
array = [];
for(key in collection) {
if (collection.hasOwnProperty(key) && key.charAt(0) != '$') {
array.push(key);
}
}
array.reverse();
} else {
array = collection || [];
}
arrayBound = array.length-1;
// we are not using forEach for perf reasons (trying to avoid #call)
var child_scopes = [];
for (index = 0, length = array.length; index < length; index++) {
key = (collection === array) ? index : array[index];
value = collection[key];
childScope = scope.$new();
child_scopes.push(childScope);
childScope[valueIdent] = value;
if (keyIdent) childScope[keyIdent] = key;
childScope.$index = index;
childScope.$first = (index === 0);
childScope.$last = (index === arrayBound);
childScope.$middle = !(childScope.$first || childScope.$last);
linker(childScope, function(clone){
cursor.before(clone);
});
}
scope.$on('$destroy', function() {
for (var i=0; i < child_scopes.length; i++) {
child_scopes[i].$destroy();
}
});
};
}
};
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment