Laravel cursorPaginate分页逻辑及SQL Server报错解决咨询
Laravel cursorPaginate 分页问题解决
一、cursorPaginate 核心工作逻辑
cursorPaginate 是基于游标而非页码的分页方案,核心逻辑简单直接:
- 必须指定排序字段(比如
orderBy('id')),每次查询会记录结果集最后一条数据的排序字段值,加密后生成游标。 - 生成
nextPageUrl()时,会自动把游标作为cursor参数拼到URL里。当下一页请求到来时,Laravel会自动解析这个cursor参数,构造where('id', '>', 游标解析出的id值)的查询,从而获取下一页数据。 - 全程不需要手动传递游标给
cursorPaginate方法,框架会自动处理。
二、带搜索条件的分页实现
你的路由代码存在语法错误,且变量名不匹配视图,修正后即可正常保留搜索条件分页:
Route::get('/users',function(Request $request){ $email = $request->get('email', null); $users = User::orderBy('id') // 仅当有email参数时才添加搜索条件 ->when($email, function($query) use ($email) { $query->where('email', $email); }) ->cursorPaginate(200); // 注意:视图里用的是$users变量,之前的versions会导致视图报错 return view('users', ['users' => $users]); });
nextPageUrl()会自动把当前请求的所有查询参数(比如email)拼到下一页链接中,jscroll请求下一页时会带上这些参数,路由就能正确识别搜索条件并过滤数据。
三、SQL Server 下的报错修复
你手动传递游标给cursorPaginate的写法是错误的——cursorPaginate的第二个参数是要查询的字段数组,不是游标值,这才导致框架把游标字符串当成了数据库列名,抛出“无效列名”的错误。
正确写法完全不需要手动传游标,框架会自动从请求参数中获取:
Route::get('/users',function(Request $request){ $users = User::orderBy('id') ->cursorPaginate(200); return view('users', ['users' => $users]); });
如果需要自定义游标参数名(比如不想用默认的cursor),可以用第三个参数指定:
// 把游标参数名改为page_cursor $users = User::orderBy('id') ->cursorPaginate(200, ['*'], 'page_cursor');
此时nextPageUrl()会自动使用page_cursor作为参数名,jscroll请求时会带上该参数,框架能正确解析。
另外需确保你的SQL Server版本为2012及以上,Laravel的cursorPaginate依赖该版本及以上的SQL语法支持。
四、视图与JS的匹配修正
你的JS中contentSelector: 'div.customRow',但Blade循环输出的是<div class="row">,两者不匹配会导致jscroll无法正确加载新内容,需统一:
<div id="scroll" style="overflow-y: scroll; height: 58vh;"> @foreach($users as $user) <div class="customRow"> {{ $user->email }} </div> @endforeach @if ($users->hasMorePages()) <a class="jscroll-next" href="{{ $users->nextPageUrl() }}"></a> @endif </div>
内容的提问来源于stack exchange,提问作者Dimitrios Desyllas
相关产品推荐
相关产品推荐

