Skip to content
techird edited this page Apr 6, 2016 · 1 revision

Step6. 添加分页支持和搜索到列表上

上一步:Step5. 支持图片元数据更新

本步骤完整源码在 workflow/step-6 分支上,提交记录为 8f7018e

如果用户上传的文件很多,那么列出全部数据将会耗费大量的时间和资源。这种情况下,我们一般会提供分页接口来支持数据分页。同时,客户端已经具有为图片添加元数据(作者、标签、Alt文本)的能力,所以客户端也希望可以通过搜索来列出相关的图片。

分页接口设计里面,一般包含 pageIndex 表示请求的页面以及 pageSize 表示请求每页的数据量。在本例,我们直接使用用户从 QueryString 传过来的这两个参数。其中 pageIndex 从 0 开始索引。

分页接口的设计里面,还要求返回给客户端总记录数,这个数据将用户客户端计算最大页码。下面,我们修改 handle/list.js 的代码,添加分页支持。

// handle/list.js

const params = request.query;

// ...connected to db
const imageCollection = db.collection("images");
const total = yield imageCollection.count();

let query = imageCollection.find();
let pageIndex = +params.pageIndex;
let pageSize = +params.pageSize;

// see if user has request for a paging
if (!isNaN(pageIndex) && !isNaN(pageSize)) {
    pageIndex = pageIndex || 0;
    pageSize = pageSize || 10;
    const start = pageIndex * pageSize;
    query = query.skip(start).limit(pageSize);
}

const list = yield query.toArray();
    
print({
    total,
    list, 
    paging: { pageIndex, pageSize } 
});

(只列出了关键代码,完整修改请参考 8f7018e

这里关键代码是 query = query.skip(start).limit(pageSize),这里的意思是跳过游标的 start 条记录,尝试取 pageSize 条记录。

同时,在输出分页列表的同时,也计算了集合里面的总记录数(使用 .count() 方法)并输出。

分页效果

现在,用户可以在 URL 上指定 pageIndexpageSize 进行分页了。在这个基础上,我们添加搜索功能。

那么,搜索应该是在分页之前还是之后呢?思考过后,发现只能在分页之前进行。否则,不能保证分页是基于搜索之后的结果的。

同时,我们统计记录总数的时候,也需要根据搜索的条件进行统计,否则就会出现「这个关键字明明有 100 条记录,怎么到了第 2 页就没数据了」这样的情形。

// handle/list.js

// ...connected to db
const imageCollection = db.collection("images");

let criteria = {};

// build search criteria
const keyword = params.search;
if (keyword) {
    const search = new RegExp(keyword);
    console.log("search: " + keyword);
    criteria.$or = ['name', 'meta.author', 'meta.labels', 'meta.alt'].map(field => ({ [field]: search }));
}

const total = yield imageCollection.count(criteria);
let query = imageCollection.find(criteria);

(只列出了关键代码,完整修改请参考 8f7018e

进行搜索的时候,我们会创建 MongoDB Query(代码中的 criteria),然后传入 find() 方法中。

上面构造了一个「或」类型的搜索,就是希望在指定的字段上匹配到了关键字,都认为记录匹配。

现在,可以试试用 Postman 测试,搜索一下作者、标签或者 Alt 文本。

搜索效果

下一步:Step7. 添加搜索历史记录