I’m not sure what you mean. I don’t have a problem indexing the values, the problem is that with collection-repeat the values that are not loaded on the current scroll (eg. items that start with letter Z that arte at the bottom of the list) will not be addressable. At least to my knowledge. Is there a way to tell the collection-repeat to scroll to a certain element?
Well, the problem now resides that I can’t really do aliasing for the collection-repeat. Any ideas?
<div collection-repeat="recipee in recipees | filter:{category:filter.category, authorId:filter.authorId} | groupByDateOrName:(grouping=='Date') track by recipee.id as filteredItems" item-height="getItemHeight(recipee, $index)" class="alpha_list" id="index_{{recipee.id}}">
...
</div>
<ul class="alpha_sidebar" ng-show="mode == 'list'">
<li ng-click="scrollTo({{g.recipeeId}})" ng-repeat="g in swipeGroup">{{g.name}}</li>
</ul>
$scope.scrollTo = function(recipeeId) {
// The following code works with ng-repeat but not with collection-repeat
//$location.hash(location);
//$ionicScrollDelegate.anchorScroll();
// collection-repeat workaround
var scrollHeight = 0;
for (var i = 0; i < $scope.filteredItems.length; i++) {
if ($scope.filteredItems[i].id == recipeeId) {
return scrollHeight;
}
scrollHeight += $scope.getItemHeight($scope.filteredItems[i], i);
}
};
I can’t use the “recipe in recipees | filter1 | filter2 as filteredItems”. Is there an alternate way to declare filters? Can I refrence the filtered list from my controller???
Step 1. Add alias to ionic’s collection repeat. Go to ionic.bundle.js on the CollectionRepeatDirective and add this to the regex.
var match = repeatExpr.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
After this, add:
var aliasAs = match[3]; // AC: Added this
// Alias test
if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) || /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
throw Error("alias " + aliasAs +" is invalid --- must be a valid JS identifier which is not a reserved name.");
}
And below on the scope.$watchCollection call, add the following before the timeout function:
scope.$watchCollection(listGetter, function(newValue) {
newValue || (newValue = []);
if (!angular.isArray(newValue)) {
throw new Error("collection-repeat expected an array for '" + listExpr + "', " +
"but got a " + typeof value);
}
// AC: Adding alias as from angular.js' ng-repeat
if (aliasAs) {
scope[aliasAs] = newValue;
}
// Wait for this digest to end before refreshing everything.
$timeout(function() {
getRepeatManager().refreshData(newValue);
if (newValue.length) refreshDimensions();
}, 0, false);
});
Step 2. On the scroll function on your controller, add the following:
$scope.scrollTo = function(recipeeId) {
// The following code works with ng-repeat but not with collection-repeat
//$location.hash(location);
//$ionicScrollDelegate.anchorScroll();
// collection-repeat workaround
var items = $scope.$$childHead.filteredItems;
var scrollHeight = 0;
for (var i = 0; i < items.length; i++) {
if (items[i].id == recipeeId) {
$ionicScrollDelegate.scrollTo(0, scrollHeight, true);
}
scrollHeight += $scope.getItemHeight(items[i], i);
}
};
Still not the best way to do it, and I have to reference the $$childHead which is suboptimal. If any of you Ionic devs have any comments or possible inclusions to collection-repeat, please let me know.
@andiCR - I am trying to get indexed list working with collection-repeat as well. I wanted to know if $scope.getItemHeight in the controller that you defined is in the ionic.bundle.js or a custom function that you wrote.
Do you have a codepen or can you share the controller code?