AngularJS paginator directive

An AngularJS directive to easily paginate any list of items The directive exposes this methods to the view: * paginatedItems() * pagesInGroup() * hasPrevGroup() * gotoPrevGroup() * hasNextGroup() * gotoNextGroup() * hasPrevPage() * gotoPrevPage() * hasNextPage() * gotoNextPage() * gotoPage() * itemsCount() * firstItemNumber() * lastItemNumber()

HTML

<div ng-app="ui" ng-controller="Ctrl" class="container">

    <button ng-click="updateProducts()">Regenerate Products List</button>
    
    <paginator
            items="products"
            items-per-page="9"
            pages-per-group="2">
            
            
        <div class="navigation">
            <div class="items-count">{{firstItemNumber()}} - {{lastItemNumber()}} of {{itemsCount()}} items</div>
            <div class="pages clearfix" ng-show="itemsCount() > itemsPerPage">
                <button ng-disabled="!hasPrevPage()" ng-click="gotoPrevPage()">&lt; Prev</button>
                <ul clearfix>
                    <li ng-show="hasPrevGroup()" ng-click="gotoPrevGroup()">
                        ...
                    </li>
        
                    <li ng-repeat="page in pagesInGroup()" ng-click="gotoPage(page.index)" ng-class="{active: page.active}">
                        {{page.index}}
                    </li>
        
                    <li ng-show="hasNextGroup()" ng-click="gotoNextGroup()">
                        ...
                    </li>
                </ul>
                <button ng-disabled="!hasNextPage()" ng-click="gotoNextPage()">Next &gt;</button>
            </div>
            <div class="sorter">
                Sort by: 
                <select ng-model="sorting">
                    <option value="-Price">Price descending</option>
                    <option value="Price">Price ascending</option>
                    <option value="Name">Name A-Z</option>
                    <option value="-Name">Name Z-A</option>
                </select> 
            </div>
        </div>
        
        <div class="items clearfix">
            <div ng-repeat="item in paginatedItems()" class="item">
                <div class="image">
                    <img ng-src="{{item.Thumb}}" alt="{{item.Name}}" />
                </div>
                <div class="name">
                    <a ng-href="{{item.Detail}}"...

CSS

.clearfix:after { 
   content: "."; 
   visibility: hidden; 
   display: block; 
   height: 0; 
   clear: both;
}

.container {
    padding: 10px;
}

.navigation {
    margin-bottom: 10px;
}

.navigation .pages > * {
    float: left;
}

.navigation .pages ul li {
    float: left;
    padding: 0 5px;
    cursor: pointer;
}

.navigation .pages ul li.active {
    font-weight: bold;
}

.items {
    border-left: 1px solid black;
    border-top: 1px solid black;
    max-width: 423px;
}

.items .item {
    float: left;
    border-bottom: 1px solid black;
    border-right: 1px solid black;
    padding: 10px;
    width: 120px;
}

.item .price {
    font-weight: bold;
}

JavaScript

/* An AngularJS directive to easily paginate any list of items */

/*
 * The directive exposes this methods to the view:
 * paginatedItems()
 * pagesInGroup()
 * hasPrevGroup()
 * gotoPrevGroup()
 * hasNextGroup()
 * gotoNextGroup()
 * hasPrevPage()
 * gotoPrevPage()
 * hasNextPage()
 * gotoNextPage()
 * gotoPage()
 * itemsCount()
 * firstItemNumber()
 * lastItemNumber()
 */

angular.module('ui', [])
    .directive('paginator', ['$filter', '$parse',
                   function ($filter,    $parse) {
        return {
            restrict: 'EA',
            scope: true,
            link: function link($scope, $element, $attrs, $controller) {
                var itemsPerPage = $attrs.itemsPerPage * 1, // cast to number
                    pagesPerGroup = $attrs.pagesPerGroup * 1, // cast to number
                    itemsPerGroup = itemsPerPage * pagesPerGroup,
                    parentScope = $scope.$parent || $scope,
                    itemsGet = $parse($attrs.items);
                
                $scope.items = itemsGet(parentScope);

                $scope.$watch(function() {
                    var parentValue = itemsGet(parentScope);

                    if (parentValue !== $scope.items) {
                        $scope.items = parentValue;
                    }

                    return parentValue;
                });
                
                $scope.itemsPerPage = itemsPerPage;
                var groups = [];
                var currentGroup = 0;
                var currentPage = 0;
                $scope.sorting = 'Price';

                function numItemsPreviousGroups() {
                    return itemsPerPage * pagesPerGroup * currentGroup;
                }
                
                function numItemsPreviousPages() {
                    return itemsPerPage * currentPage;
                }
                
                function firstItemCurrentPage() {
                    return angular.isDefined($scope.items) &&...