#Knockout-Paged.js : A Knockout Paging Plugin
##How does it work?
knockout-paged.js works by extending ko.observableArray.fn
to include an asPaged
method. This method, called as a method of an instantiated ko.observableArray
, returns the same observable array, except that it has a couple of additional propertied hanging off of it which can be used for paging. (Note: the underlying array is not modified at all)
###What are the additional properties?
The following properties are added to the instance of the observable array:
current
(Type:ko.observable(Number)
)
An observable of the current page number (starting from 1)pagedItems
(Type:ko.observableArray
)
An observable array containing only the items of the current page. (ie, the "paged items")pageSize
(Type:Number
)
The integer value of the page size (default is 10)isLoading
(Type:ko.observable(Boolean)
)
An observable indicating whether or not data is currently being retrieved from the server (only ever true for Ajaxified datasets)next
(method)
If enabled, loads the next page.previous
(method)
If enabled, loads the previous page.goToPage
(method(Number
))
Goes to the designated page. (Indexed starting at 1)clearCache
(method)
Clears the cache (for ajax-based pagination)
The paged observable array can be created by using one of the three different method signatures:
##How do I use it?
###Page locally available data easily
// data is already loaded on the client
.asPaged(Number pageSize) => ko.observableArray (self)
pageSize
: ANumber
(Integer expected) indicating the desired page size for the observable array- returns : The
ko.observableArray
instance that.asPaged
was called on, augmented with the paging methods
Example:
var ExampleViewModel = function(){
this.apples = ko.observableArray().asPaged(10);
//... data can be loaded at any time
this.apples.push({type: 'Jazz', state: 'Ripe'});
};
###Page server-side dataset with Url Template
// data is to be loaded via ajax, with a regular URL structure
.asPaged(Number pageSize, String templateUrl) => ko.observableArray (self)
pageSize
: ANumber
(Integer expected) indicating the desired page size for the observable arraytemplateUrl
: AString
representing the URL template to be used to grab the data from the server.- returns : The
ko.observableArray
instance that.asPaged
was called on, augmented with the paging methods
Example:
var Example = function(){
// apples is empty. will automatically load first page, and any other page which is requested
// by using the provided url template
this.apples = ko.observableArray().asPaged(10,'/url/to/get/apples?page={page}&pageSize={pageSize}');
};
###Configure it to do what you need with options hash
.asPaged(Object config) => ko.observableArray (self)
In this case we simply pass in an object hash with whatever options we want to set. The following options are made available:
Name | Type | Type |
---|---|---|
pageSize |
Number |
The desired page size. Expected to be an integer |
async |
Boolean |
Whether or not the dataset will be loaded asynchronously or not. Note: this may be overridden if async-only options are provided when this is set to false or vice-versa. |
url |
String |
A string template for a URL optionally containing any of the following formatters: {page} , {pageSize} , {start} , {end} which will then be replaced with the corresponding data. For example, '/resource/list/start/{start}/end/{end}' will produce '/resource/list/start/0/end/10' on initialization with default options. Note: async only
|
Function |
A function which will be expected to receive a single parameter which is an object hash containing the properties page , pageSize , start , end , and return the to be requested to get the corresponding page of data. Note: async only
|
|
cache |
Boolean |
Boolean representing whether or not the data retrieved from the server should be reused the next time the page is requested. Default is true Note: async only
|
mapFromServer |
Function |
A callback function which is called on AJAX success with the AJAX response as the only parameter. The callback is expected to return the array to be the current page. Note: async only |
ctor |
Function |
A constructor function which will be mapped to the data being pulled from the server. Note: async only |
ajaxOptions |
Object |
An options hash to be passed into the jQuery $.ajax method when a page is requested asnchronously. Note: async only
|
You can see the local data functionality demonstrated in jsFiddle here
You can see the asynchronous functionality demonstrated in jsFiddle here
Unfortunately, the source had to be hacked a little bit in order to work with jsFiddle's JSON echo API, but it demonstrates the asynchronous nature of the pager that can be achieved. If I get a bit further with this project, I will provide some more complete examples and update this article.
There is also a tutorial on Tech.Pro which was the origin of this plugin:
Handling Paged Datasets in Knockout.js
##Future Development
As this is a plugin that I believe I myself will use, I would like to keep improving on it. I am open to suggestions on the best way to do that. If you have opinions on how this API should change or be improved, please share! (or submit a pull request).
My major plans for it right now (other than fixing bugs and making it more robust) is to add support for RESTful endpoints.
My thoughts is this could go something like this:
var Example = function(){
// instead of providing a url template, you would simply provide the resource name
// and it would do the rest of the work
this.apples = ko.observableArray().asPaged({
pageSize: 10,
resource: '/apple'
});
};
RESTful API's have an entirely different way of handling paged datasets, which is by sending back one or more "next", "prev", "first", and "last" URLs along with the response. I intend on adding handling of this by default soon, and I think this could result in a very clean API. I am certainly open to suggestions here as well.
##License
MIT license - http://www.opensource.org/licenses/mit-license.php