Bene, nel precedente post abbiamo visto qual'è il problema.
Oggi vedremo come possiamo sfruttare Javascript e KnockoutJs per paginare gli elementi di una lista, tramite l'unica opzione che le API REST di SharePoint 2013 ci mettono a disposizione: una paginazione che va solo in avanti.
Vi faccio vedere subito il codice, così possiamo continuare a parlare facendo riferimento ad un esempio pratico e funzionante.

window.D4S = window.D4S || {};

window.D4S.SP2013 = window.D4S.SP2013 || {};

D4S.SP2013.ViewModel = function () {
var self = this;

//properties self.webUrl = ko.observable();
self.nextUrl = ko.observable('');
self.pageSize = ko.observable(5);
self.pageIndex = ko.observable(0);
self.contacts = ko.observableArray([]);

//methods self.ajaxCall = function (url, type, success) {
$.ajax({
url: url,
type: type,
contentType: 'application/json;odata=verbose',
headers: { 'Accept': 'application/json;odata=verbose' },
cache: false,
success: success,
error: function (jqXHR, textStatus, errorThrown) { alert(errorThrown); }
});
};
self.readContacts = function () {
if (self.pageIndex() === 0)
self.contacts.removeAll();

//url = <web site url>/_api/lists/getByTitle('Contacts')/items?$top=X&$select=Title //this is the only way to paginate a REST call to an SPList //don't use the $skip parameter! (only for list items pagination). var url = (self.nextUrl() === '') ? self.webUrl().SPItemsFromList('Contacts').SPTop(self.pageSize()).SPSelect('Title') : self.nextUrl();
var onSuccess = function (data) {
if (data.d != undefined && data.d != null) {
self.nextUrl(data.d.__next);
self.contacts(data.d.results);
self.pageIndex(self.pageIndex() + 1); //this is only for sample }
};
self.ajaxCall(url, 'GET', onSuccess);
};
self.clearContacts = function () {
self.contacts.removeAll();
self.pageIndex(0);
self.nextUrl('');
};
};

Il punto chiave, come dicevamo, è la proprietà "next".
Per prima cosa dovete fare attenzione al fatto che facendo una query REST richiedendo XML come formato di risposta avremo la URL utile alla prossima richiesta all'interno dell'attributo "next" (come abbiamo visto nel precedente post), invece, richiedendo il formato JSON come formato della risposta, questa proprietà viene serializzata nell'oggetto JSON come "__next" (con doppio underscore).
Per permette quindi la paginazione in avanti, dobbiamo creare una variabile d'appoggio per questa URL e nel caso in cui questa variabile è vuota, provvediamo a specificare la URL per la nostra prima query agli elementi di lista (utilizzando SOLO il parametro $top), se invece questa URL è valorizzata, significa che è già stata fatta una prima selezione sugli elementi della lista e che per la prossima chiamata al server dovrò utilizzare la URL presente all'interno del parametro "__next" presente nella chiamata appena effettuata.

var url = (self.nextUrl() === '') ? self.webUrl().SPItemsFromList('Contacts').SPTop(self.pageSize()).SPSelect('Title') : self.nextUrl();


Nota: nell'esempio di codice, ho utilizzato la mia libreria Javascript per produrre la query alle API REST di SharePoint 2013. Se volete utilizzarla, la potete trovare a questo indirizzo:
http://www.nuget.org/packages/d4s.sp2013.rest


L'approccio sbagliato invece, sarebbe quello di utilizzare il parametro $skip ed incrementare il suo valore moltiplicando il numero di pagina per il numero di elementi per pagina.

//url = <web site url>/_api/lists/getByTitle('Tasks')/items?$skip=X&$top=Y&$select=Title

//this call is bugged!

var url = self.webUrl().SPItemsFromList('Tasks').SPSkip(self.pageIndex() * self.pageSize()).SPTop(self.pageSize()).SPSelect('Title');


Facendo una query di questo tipo, come abbiamo visto nel precedente post, SharePoint 2013 ritorna sempre e solo i primi N elementi della lista (dove N è uguale al valore dato al parametro $top).

Vi lascio un'App SharePoint 2013 (di tipo SharePoint-hosted) che vi fa vedere sia il metodo sbagliato che quello corretto per paginare gli elementi di una lista, tramite le API REST.
- D4S.SP2013.RESTPagination.zip (1,28 MB)


Come vi dicevo, ho segnalato questo problema tramite il sito uservoice.com e potete anche voi contribuire a far arrivare la voce al team di sviluppo dando il vostro voto. Ecco l’indirizzo preciso:
http://officespdev.uservoice.com/forums/224641-general/suggestions/4606680-line-up-list-item-pagination-with-rest-api-using-