|
20 | 20 | * Config
|
21 | 21 | */
|
22 | 22 | var moduleName = 'angularUtils.directives.dirPagination';
|
| 23 | + var DEFAULT_ID = '__default'; |
23 | 24 |
|
24 | 25 | /**
|
25 | 26 | * Module
|
|
40 | 41 | priority: 5000, // This setting is used in conjunction with the later call to $compile() to prevent infinite recursion of compilation
|
41 | 42 | compile: function dirPaginationCompileFn(tElement, tAttrs){
|
42 | 43 |
|
43 |
| - // Add ng-repeat to the dom element |
44 |
| - if (tElement[0].hasAttribute('dir-paginate-start') || tElement[0].hasAttribute('data-dir-paginate-start')) { |
45 |
| - // using multiElement mode (dir-paginate-start, dir-paginate-end) |
46 |
| - tAttrs.$set('ngRepeatStart', tAttrs.dirPaginate); |
47 |
| - tElement.eq(tElement.length - 1).attr('ng-repeat-end', true); |
48 |
| - } else { |
49 |
| - tAttrs.$set('ngRepeat', tAttrs.dirPaginate); |
50 |
| - } |
51 |
| - |
52 | 44 | var expression = tAttrs.dirPaginate;
|
53 | 45 | // regex taken directly from https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js#L211
|
54 | 46 | var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
|
|
60 | 52 | var itemsPerPageFilterRemoved = match[2].replace(filterPattern, '');
|
61 | 53 | var collectionGetter = $parse(itemsPerPageFilterRemoved);
|
62 | 54 |
|
63 |
| - var paginationId = tAttrs.paginationId || '__default'; |
64 |
| - paginationService.registerInstance(paginationId); |
| 55 | + // If any value is specified for paginationId, we register the un-evaluated expression at this stage for the benefit of any |
| 56 | + // dir-pagination-controls directives that may be looking for this ID. |
| 57 | + var rawId = tAttrs.paginationId || DEFAULT_ID; |
| 58 | + paginationService.registerInstance(rawId); |
65 | 59 |
|
66 | 60 | return function dirPaginationLinkFn(scope, element, attrs){
|
| 61 | + |
| 62 | + // Now that we have access to the `scope` we can interpolate any expression given in the paginationId attribute and |
| 63 | + // potentially register a new ID if it evaluates to a different value than the rawId. |
| 64 | + var paginationId = $parse(attrs.paginationId)(scope) || attrs.paginationId || DEFAULT_ID; |
| 65 | + paginationService.registerInstance(paginationId); |
| 66 | + |
| 67 | + var repeatExpression; |
| 68 | + var idDefinedInFilter = !!expression.match(/(\|\s*itemsPerPage\s*:[^|]*:[^|]*)/); |
| 69 | + if (paginationId !== DEFAULT_ID && !idDefinedInFilter) { |
| 70 | + repeatExpression = expression.replace(/(\|\s*itemsPerPage\s*:[^|]*)/, "$1 : '" + paginationId + "'"); |
| 71 | + } else { |
| 72 | + repeatExpression = expression; |
| 73 | + } |
| 74 | + |
| 75 | + // Add ng-repeat to the dom element |
| 76 | + if (element[0].hasAttribute('dir-paginate-start') || element[0].hasAttribute('data-dir-paginate-start')) { |
| 77 | + // using multiElement mode (dir-paginate-start, dir-paginate-end) |
| 78 | + attrs.$set('ngRepeatStart', repeatExpression); |
| 79 | + element.eq(element.length - 1).attr('ng-repeat-end', true); |
| 80 | + } else { |
| 81 | + attrs.$set('ngRepeat', repeatExpression); |
| 82 | + } |
| 83 | + |
67 | 84 | var compiled = $compile(element, false, 5000); // we manually compile the element again, as we have now added ng-repeat. Priority less than 5000 prevents infinite recursion of compiling dirPaginate
|
68 | 85 |
|
69 | 86 | var currentPageGetter;
|
|
183 | 200 | },
|
184 | 201 | scope: {
|
185 | 202 | maxSize: '=?',
|
186 |
| - onPageChange: '&?' |
| 203 | + onPageChange: '&?', |
| 204 | + paginationId: '=?' |
187 | 205 | },
|
188 |
| - link: function(scope, element, attrs) { |
| 206 | + link: function dirPaginationControlsLinkFn(scope, element, attrs) { |
189 | 207 |
|
190 |
| - var paginationId; |
191 |
| - paginationId = attrs.paginationId || '__default'; |
192 |
| - if (!scope.maxSize) { scope.maxSize = 9; } |
193 |
| - scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true; |
194 |
| - scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false; |
| 208 | + // rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has |
| 209 | + // not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is |
| 210 | + // no corresponding dir-paginate directive and wrongly throwing an exception. |
| 211 | + var rawId = attrs.paginationId || DEFAULT_ID; |
| 212 | + var paginationId = scope.paginationId || attrs.paginationId || DEFAULT_ID; |
195 | 213 |
|
196 |
| - if (!paginationService.isRegistered(paginationId)) { |
197 |
| - var idMessage = (paginationId !== '__default') ? ' (id: ' + paginationId + ') ' : ' '; |
| 214 | + if (!paginationService.isRegistered(paginationId) && !paginationService.isRegistered(rawId)) { |
| 215 | + var idMessage = (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' '; |
198 | 216 | throw 'pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive.';
|
199 | 217 | }
|
200 | 218 |
|
| 219 | + if (!scope.maxSize) { scope.maxSize = 9; } |
| 220 | + scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true; |
| 221 | + scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false; |
| 222 | + |
201 | 223 | var paginationRange = Math.max(scope.maxSize, 5);
|
202 | 224 | scope.pages = [];
|
203 | 225 | scope.pagination = {
|
|
291 | 313 |
|
292 | 314 | return function(collection, itemsPerPage, paginationId) {
|
293 | 315 | if (typeof (paginationId) === 'undefined') {
|
294 |
| - paginationId = '__default'; |
| 316 | + paginationId = DEFAULT_ID; |
295 | 317 | }
|
296 | 318 | if (!paginationService.isRegistered(paginationId)) {
|
297 | 319 | throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.';
|
|
0 commit comments