Paginación del lado del servidor Quasar Table y AdonisJS

El paginado del lado del servidor del componente Table de Quasar utilizando AdonisJS se basa en los siguientes parámetros de entrada: sortBy, descending, page, rowsPerPage y rowsNumber.

Del lado del cliente tendremos el componente Table de Quasar en el cual juegan el papel fundamental las propiedades pagination y filter así como el evento @request.

<q-table :pagination.sync="pagination" :filter="filter" @request="onRequest" ..../>

En el data de nuestro SFC declaramos el objeto pagination, la propiedad filter y en methods nuestro manipulador del evento @request.
filter: '',
pagination: {
sortBy: 'username',
descending: true,
page: 1,
rowsPerPage: 10,
rowsNumber: 0
},
En el siguiente código javascript se puede apreciar, utilizando axios, la llamada que será realizada al servidor teniendo siempre en cuenta que cuando el componente Table invoca al evento @request le pasa como parámetro un objeto con las llaves pagination  y filter 

Cuando queremos invocar manualmente el método declarado para el evento @request no debemos dejar de pasar este objeto.

async onRequest(props) {
let {page, rowsPerPage, sortBy, descending} = props.pagination;
let filter = props.filter;

let startRow = (page - 1) * rowsPerPage;
await this.$axios.post('url de lado del servidor', {
startRow, rowsPerPage, filter, sortBy, descending
}).then(r => {
if (r.data.code !== 'Ok') return Error.call(this, resources.eGetUsers);
this.users = r.data.dt.rows;
this.pagination.rowsNumber = r.data.dt.recordsFiltered;
this.pagination.page = page;
this.pagination.rowsPerPage = rowsPerPage;
this.pagination.sortBy = sortBy;
this.pagination.descending = descending;
}).catch(e => {
Error.call(this, resources.eGetUsers);
console.error(e);
});
},

Hasta aquí hemos resuelto la manipulación del lado del cliente. Ahora vamos a ver que se debe realizar del lado del servidor para procesar la petición utilizando axios y retornar el contenido hacia el componente Table de Quasar

La solución que me dispuse a realizar se basó en las siguientes ideas a partir de las entradas del componente Table:
1. Limitar la cantidad de registros a retornar del servidor al cliente.
2. Ordenamiento según una columna determinada.
3. Filtrado utilizando una cadena por cada una de las columnas que se permita realizar la búsqueda.
4. Otras comparaciones fuera del componente Table para permitir mayor funcionalidad al Table de Quasar.

Con estas ideas entonces construí la siguiente clase que nos permitirá la manipulación del lado del servidor de las peticiones del componente Table de Quasar.

'use strict';
/*
|--------------------------------------------------------------------------
| Autor: Lic. Alain Ramirez Cabrejas
|--------------------------------------------------------------------------
| startRow: startRow = (page - 1) * rowsPerPage
| rowsPerPage: Filas por páginas
| filter: string a buscar en todas las columnas que se determine en columns
| sortBy: Columna para realizar el ordenamiento
| descending: Tipo de ordenamiento ascesdente (asc) o descendente (desc)
|--------------------------------------------------------------------------
*/

const Database = use('Database')

class Datatable {
limit(query, request) {
if ('startRow' in request && 'rowsPerPage' in request && request.rowsPerPage !== 0) {
query.offset(request.startRow).limit(request.rowsPerPage);
}
}

order(query, request) {
if ('sortBy' in request && request.sortBy !== null) {
if ('descending' in request && request.descending) {
query.orderBy(request.sortBy, 'desc');
} else {
query.orderBy(request.sortBy, 'asc');
}
}
}

filter(query, request, columns) {
if ('filter' in request && request.filter !== null) {
columns.forEach(col => {
if ('search' in col) query.orWhereRaw(`${col.db} like '%${request.filter}%'`);
})
}
}

whereRaw(query, where) {
if (where && where.length !== 0) {
where.forEach(el => {
query.whereRaw(el)
})
}
}

async execute(request, table, primaryKey, columns, where) {
let query = Database.from(table);
this.filter(query, request, columns);
this.whereRaw(query, where)
let clone = query.clone();
this.limit(query, request);
this.order(query, request);
query.select(columns.map(el => {
return el.db;
}));
return {
recordsTotal: (await Database.from(table).getCount()),
recordsFiltered: (await clone.getCount()),
rows: await query
}
}
}

module.exports = Datatable;

Este sencillo desarrollo lo podemos perfeccionar aún más según las necesidades o implementaciones de las peticiones realizadas por el componente Table de Quasar.

Los códigos de procesamiento de peticiones puede ser encontrado en github

Gracias...

Comentarios

Publicar un comentario

Entradas populares de este blog

Fingerprint WSQ library

AdonisJS un Framework que promete