Skip to content
Knockout Extension/Plugin for common paged-data scenarios
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
ext
test_json
.gitattributes
.gitignore
LICENSE.md
README.md
index.html
knockout-paged.js
tp-tutorial.md

README.md

#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 : A Number (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 : A Number (Integer expected) indicating the desired page size for the observable array
  • templateUrl : A String 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

You can’t perform that action at this time.