You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含18000条数据的Select2实现分段加载?(基于Medoo框架)

嘿,我来帮你解决Select2加载18000条数据卡顿的问题!上万条数据一次性渲染肯定会拖慢页面,Select2本身支持远程数据加载(也就是你说的分段展示),结合Medoo实现起来很简单,咱们一步步来:

1. 调整前端HTML结构

首先把原来手动渲染所有<option>的代码改成空的下拉框,因为数据要通过远程请求动态加载:

<div class="form-group">
    <label for="nama_user"><?php _e('Nama User'); ?></label>
    <select class="form-control select2" id="nama_user" name="nama_user" style="width: 100%;">
        <option value="0"><?php _e('Nobody'); ?></option>
        <!-- 不再手动渲染所有选项,由Select2远程加载 -->
    </select>
</div>

2. 修改Select2的JS配置

给Select2加上AJAX远程加载的配置,让它根据用户输入和页码分段拉取数据:

$(".select2").select2({
    ajax: {
        url: 'ldap-search.php', // 后面要写的后端接口路径
        dataType: 'json',
        delay: 250, // 输入延迟250ms,减少频繁请求
        data: function (params) {
            return {
                q: params.term, // 用户输入的搜索关键词
                page: params.page || 1 // 当前请求的页码,默认第1页
            };
        },
        processResults: function (data, params) {
            params.page = params.page || 1;
            return {
                results: data.items, // 渲染下拉选项的数组
                pagination: {
                    more: (params.page * 20) < data.total_count // 判断是否还有更多数据
                }
            };
        },
        cache: true // 开启缓存,重复搜索直接用之前的结果
    },
    placeholder: '<?php _e('Search user...'); ?>',
    minimumInputLength: 1, // 至少输入1个字符才触发搜索(可选,按需调整)
    escapeMarkup: function (markup) { return markup; } // 防止XSS攻击,默认已处理
});

3. 编写后端Medoo分页查询接口

新建一个ldap-search.php文件,用来处理前端的AJAX请求,用Medoo做带搜索的分页查询:

<?php
// 初始化Medoo数据库连接(替换成你的数据库配置)
require_once 'path/to/medoo.php';
$database = new medoo([
    'database_type' => 'mysql',
    'database_name' => 'your_db_name',
    'server' => 'localhost',
    'username' => 'your_db_user',
    'password' => 'your_db_pwd'
]);

// 获取前端传递的参数
$search_term = $_GET['q'] ?? '';
$page = (int)$_GET['page'] ?? 1;
$per_page = 20; // 每页加载20条,可根据需求调整
$offset = ($page - 1) * $per_page;

// 构建查询条件:支持模糊搜索用户名
$where = [];
if (!empty($search_term)) {
    $where['nama_user[~]'] = "%{$search_term}%";
}

// 分页查询数据和总条数
$ldap_data = $database->select('ldap', ['id', 'nama_user'], [
    'WHERE' => $where,
    'LIMIT' => [$offset, $per_page],
    'ORDER' => 'nama_user ASC'
]);
$total_count = $database->count('ldap', $where);

// 转换为Select2需要的格式
$select2_items = [];
foreach ($ldap_data as $item) {
    $select2_items[] = [
        'id' => $item['id'],
        'text' => $item['nama_user']
    ];
}

// 返回JSON格式数据
header('Content-Type: application/json');
echo json_encode([
    'items' => $select2_items,
    'total_count' => $total_count
]);
exit;
?>

4. 清理原有代码

最后回到你的页面逻辑代码,把原来一次性加载所有ldap数据的代码删掉:

case "gemilang/add":
    $contacts = getTable("contacts");
    if($isAdmin) {
        $assets = getTable("assets");
    } else {
        $assets = getTableFiltered("assets","clientid",$liu['clientid']);
    }
    $clients = getTable("clients");
    $cabang_gemilang = getTable("cabang_gemilang");
    // 删掉下面这行,因为数据现在远程加载了
    // $ldap = getTable("ldap");
    $admins = getTableFiltered("people","type","admin");
    if($isAdmin) {
        $users = getTableFiltered("people","type","user");
    } else {
        $users = getTableFiltered("people","type","user","clientid",$liu['clientid']);
    }
break;

一些优化建议

  • 给ldap表的nama_user字段加个索引,模糊搜索会更快;
  • 可以根据需求调整per_page的数值,比如改成30条每页;
  • 测试时打开浏览器控制台的Network标签,查看AJAX请求是否正常,返回的JSON格式是否符合要求。

内容的提问来源于stack exchange,提问作者Zakario Lesrahmanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:36:02