You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JQGrid(loadonce=false)分页与列筛选失效问题求助(Laravel 5.8后端)

解决Laravel 5.8 + jqGrid 4.6分页与筛选问题

我之前刚好处理过Laravel配合jqGrid的类似场景,你遇到的问题核心是当loadonce: false时,jqGrid会把分页、排序、筛选的参数都通过URL传给后端,需要你在Laravel里对应处理这些参数,然后返回符合jqGrid格式的响应。先给你拆解下你看到的请求参数含义,再一步步写后端实现。

一、先搞懂jqGrid传的请求参数含义

你看到的URL参数里,每个字段的作用是:

  • _search: 布尔值,标识是否有筛选条件(true=有筛选,false=无)
  • nd: 时间戳,用来防止缓存,后端可以直接忽略
  • rows: 每页显示的记录数(分页大小)
  • page: 当前请求的页码
  • sidx: 排序的列名(对应你数据库的字段,比如你这里的NUM_CERFA
  • sord: 排序方向(asc=升序,desc=降序)
    如果是列筛选触发的请求,还会多一个filters参数,是JSON格式的筛选条件,后面会讲怎么解析。

二、Laravel后端实现步骤

假设你的模型是Cerfa,对应的控制器是CerfaController,方法对应你的路由listes/cerfa/json/null,下面是具体代码:

1. 接收请求参数

在控制器方法里,先获取所有请求参数:

use Illuminate\Http\Request;
use App\Models\Cerfa; // 假设你的模型路径是这个

public function jsonList(Request $request)
{
    // 获取分页与排序参数,设置默认值防止空参数报错
    $page = $request->get('page', 1);
    $rowsPerPage = $request->get('rows', 10);
    $sortField = $request->get('sidx', 'NUM_CERFA');
    $sortDirection = $request->get('sord', 'asc');
    $isSearch = $request->get('_search', false);
    $filters = $request->get('filters', '');
}

2. 构建查询(处理筛选、排序)

先初始化基础查询,再根据筛选条件和排序参数调整:

// 初始化基础查询
$query = Cerfa::query();

// 处理筛选条件
if ($isSearch && !empty($filters)) {
    // 解析jqGrid的filters JSON字符串
    $filterRules = json_decode($filters, true);
    if (isset($filterRules['rules'])) {
        $groupOp = $filterRules['groupOp'] ?? 'AND'; // 默认AND逻辑

        if ($groupOp === 'AND') {
            foreach ($filterRules['rules'] as $rule) {
                $this->addFilterCondition($query, $rule);
            }
        } else {
            // OR逻辑需要用闭包包裹
            $query->orWhere(function ($q) use ($filterRules) {
                foreach ($filterRules['rules'] as $rule) {
                    $this->addFilterCondition($q, $rule);
                }
            });
        }
    }
}

// 处理排序
$query->orderBy($sortField, $sortDirection);

// 封装筛选条件的私有方法,避免重复代码
private function addFilterCondition($query, $rule)
{
    $field = $rule['field'];
    $op = $rule['op'];
    $value = $rule['data'];

    switch ($op) {
        case 'eq':
            $query->where($field, '=', $value);
            break;
        case 'cn':
            $query->where($field, 'like', "%{$value}%");
            break;
        case 'gt':
            $query->where($field, '>', $value);
            break;
        case 'lt':
            $query->where($field, '<', $value);
            break;
        case 'ne':
            $query->where($field, '!=', $value);
            break;
        case 'ge':
            $query->where($field, '>=', $value);
            break;
        case 'le':
            $query->where($field, '<=', $value);
            break;
        // 可以根据你的需求添加更多操作符
    }
}

3. 处理分页并计算总数据

用Laravel的查询构造器手动处理分页,同时计算总记录数和总页数:

// 获取总记录数
$totalRecords = $query->count();
// 计算总页数
$totalPages = ceil($totalRecords / $rowsPerPage);
// 获取当前页数据
$cerfas = $query->skip(($page - 1) * $rowsPerPage)->take($rowsPerPage)->get();

4. 组装jqGrid需要的响应格式

jqGrid要求返回的JSON必须包含total(总页数)、page(当前页)、records(总记录数)、rows(当前页数据数组):

// 把模型数据转换成jqGrid需要的格式
$rowsData = $cerfas->map(function ($cerfa) {
    return [
        'id' => $cerfa->id, // jqGrid推荐每行带唯一id,方便后续操作
        'cell' => [
            $cerfa->NUM_CERFA,
            $cerfa->你的字段1,
            $cerfa->你的字段2,
            // 顺序要和你jqGrid列配置的顺序完全对应
        ]
    ];
})->toArray();

// 返回JSON响应
return response()->json([
    'total' => $totalPages,
    'page' => $page,
    'records' => $totalRecords,
    'rows' => $rowsData
]);

三、注意事项

  • 确保jqGrid列配置的name属性和数据库字段名完全对应,否则排序和筛选会失效。
  • 测试时可以直接在浏览器访问带参数的URL,查看返回的JSON格式是否符合要求,再结合Network Tab排查问题。
  • 如果需要处理更复杂的筛选(比如日期范围),可以在addFilterCondition方法里扩展对应的操作符逻辑。

内容的提问来源于stack exchange,提问作者Hippolyte Massiot

火山引擎 最新活动