I wrote a small directive that monitors objects and automatically adds the $ header property to the first in the list. Use it like this:
<div ng-repeat="item in data.items | orderBy:... | filter:... as filteredItems" header-list objects="filteredItems" header="getHeader"> <div ng-show="item.$header">{{item.$header}}</div> <div>Your normal content</div> </div>
You can pass a function that builds the title as you wish. A function can be an instance method or a function in your scope. To get the first letter, define in your controller.
$scope.getHeader = function(item) { return item.name.slice(0, 1); },
The list will be automatically updated when filters and orders are changed.
app.module("...").directive('headerList', function () { return { restrict: 'A', scope: { objects: '=', header: '=' // This must be a function or instance method }, link: function(scope) { scope.$watch('objects', function() { var lastHeader, currentHeader; scope.objects.forEach(function (obj) { // We pass obj twice, so it can be used is instance method or regular function that takes the object as argument. currentHeader = scope.header.call(obj, obj); // in order to display a header per type, we mark the first event of each kind as header if (currentHeader !== lastHeader) { obj.$header = currentHeader; lastHeader = currentHeader; } else { obj.$header = null; } }); }); } } });
Felix source share