blog icon indicating copy to clipboard operation
blog copied to clipboard

indexedDB插件库indb.js分页查询方法

Open xianzou opened this issue 5 years ago • 0 comments

用来进行处理带条件分页的场景,传入页数获取总页数和分页信息;

conditions是查询条件,如果没有传入查询条件,则通过db.count()获取总页数,通过索引index(自增)来获取值的范围;

如果是有条件的查询的话,目前的做法是通过油标去遍历所有的项,然后根据页数来判断是否可以存储到数组中,总页数也是遍历所有的数组

//创建一个迭代器
function iterateor(fn, pageInfo = {}) {
    const {
        indbSocurse,
        index,
        // currentPage = 1,
        // conditions = [],
        // pageSize,
        // pageStart = 1,
        // pageEnd = 10,
    } = pageInfo;

    const range = null;

    // 没有查询条件
    // if (!conditions.length && isAutoIncerment) {
    //     range = IDBKeyRange.bound(
    //         pageStart,
    //         pageEnd,
    //         false,
    //         false
    //     );
    // }
    return new Promise((resolve, reject) => {

        indbSocurse.cursor({
            writable: false,
            direction: 'next',
            index,
            range,
            onTouch: (cursor, owner) => {
                const next = () => cursor.continue();
                const stop = () => {
                    owner.objectStore.transaction.onabort();
                    resolve();
                };

                fn(cursor, next, stop);
            },
            onDone: () => {
                resolve();
            },
            onError: e => {
                reject(e);
            }
        });
    });
}

/** **
   * function ==> 获取列表信息
   * 参数解释
   *  pageSize 一页多少条 number
   *  conditions 条件 Array [{age:18},{name:'xxx'}] 注意 如果是string类型的使用indexOf查找,否则使用 ===
   *  indbSocurse indexdb数组源 示例:const indbSocurse = idb.use("students");
   *  index 索引名称,如果是autoIncerment,不传或者为空,如果没有设置,则传入在new InDB中的配置的index的name,和keyPath对应
   *  currentPage 当前第几页
   *  return {
   *      total,
   *      pageSize,
   *      pageNumber,
   *      data,
   *      currentPage
   *  }
   *
*/
export const queryList = async ({
    indbSocurse = {},
    conditions = [],
    pageSize = 10,
    index = '',
    currentPage = 1,
    // isAutoIncerment = false
}) => {
    // 判断indbSocurse是不是正确的对象
    if (!indbSocurse.db) {
        throw Error('indbSocurse必须是一个idb实例化对象');
    }
    const data = [];
    let total = 0;
    // 计算当前页的开始和结束
    const pageStart = (currentPage - 1) * pageSize + 1;
    const pageEnd = currentPage * pageSize;

    // if (!conditions.length) {
    //     // const test = await indbSocurse.some(10, 1);
    //     const test = await indbSocurse.first();

    // }
    await iterateor(
        (cursor, next, stop) => {
            // 判断是否符合条件
            const isMeet = [];

            for (const row of conditions) {
                if (typeof row[Object.keys(row)] === 'string') {
                    isMeet.push(
                        cursor.value[Object.keys(row)].indexOf(row[Object.keys(row)]) >
                        -1);
                } else {
                    isMeet.push(cursor.value[Object.keys(row)] === row[Object.keys(row)]);
                }
            }
            if (!isMeet.includes(false)) {
                total++;
                if (total >= pageStart && total <= pageEnd) {
                    data.push(cursor.value);
                }
            }
            next();

        },
        {
            indbSocurse,
            index,
            currentPage,
            conditions,
            pageSize,
            pageStart,
            pageEnd,
        }
    );
    if (!conditions.length) {
        // 没有查询条件
        total = await indbSocurse.count();
    }
    // 总共多少页
    const pageNumber = Math.ceil(total / pageSize);

    return {
        total,
        pageSize,
        pageNumber,
        data,
        currentPage
    };
};

xianzou avatar Jan 09 '20 08:01 xianzou