在网站前端展示大量文档时,分页导航是提升用户体验和管理数据加载效率的关键功能。安企CMS(AnQiCMS)提供了强大且灵活的API接口,让您能够轻松地在前端实现文档列表的分页功能。本文将详细介绍如何利用archive/list接口中的pagetotal参数,构建一个功能完善的分页导航。


理解安企CMS分页机制的核心

要构建文档列表的分页导航,我们主要依赖安企CMS的archive/list接口。这个接口不仅能获取文档数据,还能在特定条件下返回总文档数量,这正是我们构建分页导航所必需的关键信息。

这里有两个核心参数需要特别注意:

  1. type="page":这是获取分页信息的基础。当您在请求中设置typepage时,安企CMS的接口除了返回当前页的文档数据(data),还会额外返回一个total字段,它包含了符合当前查询条件的所有文档的总数量。如果未设置此参数或设置为其他值(如list),则不会返回total
  2. pagelimit
    • page参数指定了您希望获取的是第几页的内容。
    • limit参数则定义了每一页显示多少条文档。

通过这三个参数的巧妙配合,我们就能从后端获取到构建分页所需的所有数据。

前端实现分页导航的步骤

接下来,我们以一个典型的场景为例,详细讲解如何在前端构建分页导航。假设我们需要展示某个分类下的文章列表,每页显示10篇文章。

第一步:发起API请求并获取数据

首先,您的前端应用需要向安企CMS的API接口发送请求。这个请求会包含我们之前提到的typepagelimit参数,以及您可能需要的其他筛选条件,例如moduleId(模型ID)和categoryId(分类ID)。

async function fetchDocuments(currentPage = 1, itemsPerPage = 10, categoryId = 1) {
    const domain = 'https://yourdomain.com'; // 替换为您的域名
    const apiUrl = `${domain}/api/archive/list`;

    // 构建请求参数
    const params = new URLSearchParams({
        moduleId: 1, // 假设文章模型ID为1
        categoryId: categoryId,
        type: 'page', // 关键:获取total总数
        page: currentPage,
        limit: itemsPerPage
    });

    try {
        const response = await fetch(`${apiUrl}?${params.toString()}`);
        const result = await response.json();

        if (result.code === 0) {
            const documents = result.data; // 当前页的文档列表
            const totalDocuments = result.total; // 符合条件的总文档数量

            // 在这里处理文档列表和总数
            console.log('当前页文档:', documents);
            console.log('总文档数量:', totalDocuments);

            // 调用函数构建分页导航
            renderPagination(currentPage, itemsPerPage, totalDocuments, categoryId);
            // 调用函数渲染文档列表
            renderDocumentList(documents);

        } else {
            console.error('获取文档列表失败:', result.msg);
        }
    } catch (error) {
        console.error('请求发生错误:', error);
    }
}

// 示例调用,获取分类ID为1的第一页文章,每页10条
fetchDocuments(1, 10, 1);

这段代码演示了如何使用JavaScript的fetch API向安企CMS发送请求,并从响应中获取data(当前页文档列表)和total(文档总数)。

第二步:计算总页数并构建分页导航UI

获取到totalDocuments(总文档数量)后,结合itemsPerPage(每页显示数量),我们就可以计算出总页数,并据此生成分页导航的HTML结构。

function renderPagination(currentPage, itemsPerPage, totalDocuments, categoryId) {
    const totalPages = Math.ceil(totalDocuments / itemsPerPage); // 计算总页数
    const paginationContainer = document.getElementById('pagination-container'); // 假设页面中有这个元素来承载分页

    if (!paginationContainer) return; // 如果没有找到容器,则不渲染

    let paginationHtml = '';

    // 生成“首页”和“上一页”按钮
    paginationHtml += `<a href="#" onclick="fetchDocuments(1, ${itemsPerPage}, ${categoryId})" ${currentPage === 1 ? 'class="disabled"' : ''}>首页</a>`;
    paginationHtml += `<a href="#" onclick="fetchDocuments(${currentPage - 1}, ${itemsPerPage}, ${categoryId})" ${currentPage === 1 ? 'class="disabled"' : ''}>上一页</a>`;

    // 生成页码链接(这里为了简化,只显示部分页码)
    const maxPageLinks = 5; // 最多显示5个页码
    let startPage = Math.max(1, currentPage - Math.floor(maxPageLinks / 2));
    let endPage = Math.min(totalPages, startPage + maxPageLinks - 1);

    if (endPage - startPage + 1 < maxPageLinks) {
        startPage = Math.max(1, endPage - maxPageLinks + 1);
    }

    for (let i = startPage; i <= endPage; i++) {
        paginationHtml += `<a href="#" onclick="fetchDocuments(${i}, ${itemsPerPage}, ${categoryId})" ${currentPage === i ? 'class="active"' : ''}>${i}</a>`;
    }

    // 生成“下一页”和“尾页”按钮
    paginationHtml += `<a href="#" onclick="fetchDocuments(${currentPage + 1}, ${itemsPerPage}, ${categoryId})" ${currentPage === totalPages ? 'class="disabled"' : ''}>下一页</a>`;
    paginationHtml += `<a href="#" onclick="fetchDocuments(${totalPages}, ${itemsPerPage}, ${categoryId})" ${currentPage === totalPages ? 'class="disabled"' : ''}>尾页</a>`;

    paginationContainer.innerHTML = paginationHtml;
}

// 示例函数:渲染文档列表(根据您的模板结构自行实现)
function renderDocumentList(documents) {
    const documentListContainer = document.getElementById('document-list'); // 假设页面中有这个元素
    if (!documentListContainer) return;
    documentListContainer.innerHTML = documents.map(doc => `
        <div class="document-item">
            <h3><a href="${doc.link || '#'}">${doc.title}</a></h3>
            <p>${doc.description || ''}</p>
            <small>发布时间: ${new Date(doc.created_time * 1000).toLocaleDateString()}</small>
        </div>
    `).join('');
}

在上述renderPagination函数中,我们首先计算出总页数totalPages。接着,我们动态生成了“首页”、“上一页”、具体的页码链接、“下一页”和“尾页”按钮。当用户点击这些链接时,通过调用fetchDocuments函数,并传入新的page参数,就可以重新加载对应页面的文档数据。

为了提供更好的用户体验,我们还添加了disabledactive类名,以便通过CSS样式来区分当前页和不可点击的按钮(例如,在第一页时禁用“上一页”)。

第三步:页面加载与事件处理

为了在页面初次加载时显示第一页内容和分页导航,您可以在页面加载完成后调用fetchDocuments函数。

”`html <!DOCTYPE html>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>安企CMS文档列表</title>
<style>
    .pagination a {
        display: inline-block;
        padding: 8px 16px;
        margin: 0 4px;
        border: 1px solid #ddd;
        text-decoration: none;
        color: #337ab7;
        border-radius: 4px;
    }
    .pagination a.active {
        background-color: #337ab7;
        color: white;
        border: 1px solid #337ab7;
    }
    .pagination a.disabled {
        color: #ccc;
        pointer-events: none;
        cursor: default;
    }
    .document-item {
        border-bottom: 1px dashed #eee;
        padding: 10px 0;
        margin-bottom: 10px;
    }
</style>

<h1>文章列表</h1>
<div id="document-list">
    <!-- 文档列表将在这里加载 -->
    加载中...
</div>
<div id="pagination-container" class="pagination">
    <!-- 分页导航将在这里加载 -->
</div>

<script>
    // 上文的 fetchDocuments, renderPagination, renderDocumentList 函数放在这里
    // ... (此处省略函数的重复代码) ...

    // 页面加载完成后立即