如何为含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
相关产品推荐
相关产品推荐

