UNPKG

ng2-pagination

Version:
122 lines (121 loc) 4.98 kB
"use strict"; var core_1 = require("@angular/core"); var pagination_service_1 = require("./pagination.service"); var LARGE_NUMBER = Number.MAX_SAFE_INTEGER; var PaginatePipe = (function () { function PaginatePipe(service) { this.service = service; // store the values from the last time the pipe was invoked this.state = {}; } PaginatePipe.prototype.transform = function (collection, args) { // When an observable is passed through the AsyncPipe, it will output // `null` until the subscription resolves. In this case, we want to // use the cached data from the `state` object to prevent the NgFor // from flashing empty until the real values arrive. if (args instanceof Array) { // compatible with angular2 before beta16 args = args[0]; } if (!(collection instanceof Array)) { var _id = args.id || this.service.defaultId; if (this.state[_id]) { return this.state[_id].slice; } else { return collection; } } var serverSideMode = args.totalItems && args.totalItems !== collection.length; var instance = this.createInstance(collection, args); var id = instance.id; var start, end; var perPage = instance.itemsPerPage; this.service.register(instance); if (!serverSideMode && collection instanceof Array) { perPage = +perPage || LARGE_NUMBER; start = (instance.currentPage - 1) * perPage; end = start + perPage; var isIdentical = this.stateIsIdentical(id, collection, start, end); if (isIdentical) { return this.state[id].slice; } else { var slice = collection.slice(start, end); this.saveState(id, collection, slice, start, end); this.service.change.emit(id); return slice; } } // save the state for server-side collection to avoid null // flash as new data loads. this.saveState(id, collection, collection, start, end); return collection; }; /** * Create an PaginationInstance object, using defaults for any optional properties not supplied. */ PaginatePipe.prototype.createInstance = function (collection, args) { var config = args; this.checkConfig(config); return { id: config.id || this.service.defaultId(), itemsPerPage: config.itemsPerPage || 0, currentPage: config.currentPage || 1, totalItems: config.totalItems || collection.length }; }; /** * Ensure the argument passed to the filter contains the required properties. */ PaginatePipe.prototype.checkConfig = function (config) { var required = ['itemsPerPage', 'currentPage']; var missing = required.filter(function (prop) { return !(prop in config); }); if (0 < missing.length) { throw new Error("PaginatePipe: Argument is missing the following required properties: " + missing.join(', ')); } }; /** * To avoid returning a brand new array each time the pipe is run, we store the state of the sliced * array for a given id. This means that the next time the pipe is run on this collection & id, we just * need to check that the collection, start and end points are all identical, and if so, return the * last sliced array. */ PaginatePipe.prototype.saveState = function (id, collection, slice, start, end) { this.state[id] = { collection: collection, size: collection.length, slice: slice, start: start, end: end }; }; /** * For a given id, returns true if the collection, size, start and end values are identical. */ PaginatePipe.prototype.stateIsIdentical = function (id, collection, start, end) { var state = this.state[id]; if (!state) { return false; } var isMetaDataIdentical = state.size === collection.length && state.start === start && state.end === end; if (!isMetaDataIdentical) { return false; } return state.slice.every(function (element, index) { return element === collection[start + index]; }); }; PaginatePipe.decorators = [ { type: core_1.Pipe, args: [{ name: 'paginate', pure: false },] }, ]; /** @nocollapse */ PaginatePipe.ctorParameters = function () { return [ { type: pagination_service_1.PaginationService, }, ]; }; return PaginatePipe; }()); exports.PaginatePipe = PaginatePipe;