Laravel 多页分页
Posted
技术标签:
【中文标题】Laravel 多页分页【英文标题】:Laravel Multiple Pagination in one page 【发布时间】:2014-07-27 23:39:40 【问题描述】:我的分页有点问题。 我有两个表,其中包含来自数据库的数据,并使用 laravel Paginator 对其进行了分页。
现在我的问题是,例如,当您转到第 2 页时,它会添加 ?page=2 但这会使第一个表也转到第 2 页。
有没有办法得到这样的东西?
page_table1=number&page_table2=number
因此您不会将页面更改应用于其他表。
【问题讨论】:
【参考方案1】:在我看来,您需要更新分页工具,以便它有一个额外的参数来标识表,因为它不够聪明,无法知道同一页面上可能有 2 个自身实例.. DOH!
不必通过 URL 为所有表设置当前页面,理想情况下,您希望通过表 id 在会话中存储活动页码 THEN,您的脚本只需要担心指令而不用担心确保它携带现有页码。
这是一个非常草稿的概念......
// The page would be $tableId + "," + $pageNum
// Passed as a value of "page"
$goTo = "$tableId,$pageNum";
?page=$goTo
然后,当它到达获取表格数据的部分时,它会执行类似的操作
if(!empty($_GET["page"]))
list($tableId,$pageNum) = explode(",",$_GET["page"]);
// Store table's active page number
$_SESSION["_tableBrowser"][$tableId] = $pageNum;
// Your table reader would then look at the session for the active page number
// and not what is in $_GET
【讨论】:
【参考方案2】:很遗憾,我现在无法测试此代码,但浏览文档和代码(Illuminate/Pagination/Environment
)我猜你可以这样:
# use default 'page' for this
$collection1 = Model::paginate(20);
# use custom 'other_page' for this
$collection2 = Model2::paginate(20);
$collection2->setPageName('other_page');
setPageName()
方法未在文档中记录,但它是与文档中指示的方法一起的公共方法,因此它应该可以正常工作。作为参考,这是声明(vendor/laravel/framework/src/Illuminate/Pagination/Environment.php
中的 l. 171-180):
/**
* Set the input page parameter name used by the paginator.
*
* @param string $pageName
* @return void
*/
public function setPageName($pageName)
$this->pageName = $pageName;
现在考虑到您将有另一个查询字符串附加到 url,因此您需要告诉分页考虑它。使用appends()
方法:
$collection1->appends(array_except(Request::query(), 'page'))->links();
$collection2->appends(array_except(Request::query(), 'other_page'))->links();
也就是说,告诉每个 Presenter 使用所有查询字符串(由Request::query()
产生的数组没有分页器使用的当前索引,否则你最终会得到双值)。 array_except()
是 Laravel 内置的数组助手,它返回给定的数组(第一个参数),清除了传递的索引(第二个参数)。
我会尽快测试这段代码,但它应该可以工作。无论如何,请告诉我!
【讨论】:
我无法使用您描述的方法得到任何工作。你在哪里?$collection2->setPageName('other_page');
>>> call_user_func_array() 期望参数 1 是一个有效的回调,类 'Illuminate\Support\Collection' 没有方法 'setPageName'
对于反对者,请考虑到这个答案可能指的是与您现在正在使用的版本不同的 Laravel 版本,当时可能会起作用不适用于较新的版本。只是说。
@DamienPirsy 你知道这在 laravel 5.6 中是否仍然有效吗?我知道已经有一段时间了
我认为这个答案没有用过,我已经检查了版本,您必须在 ::paginate
上提供页面名称才能使其生效,总是有【参考方案3】:
这是我在 Laravel 4 上找到的简单解决方案。
控制器
在制作分页器之前更改页面名称:
Paginator::setPageName('page_a');
$collection_A = ModelA::paginate(10);
Paginator::setPageName('page_b');
$collection_B = ModelB::paginate(10);
查看
做同样的事情:在打印链接之前更改页面名称
Paginator::setPageName('page_a');
$collection_A->links();
Paginator::setPageName('page_b');
$collection_B->links();
如果您不想在导航到另一个页面时丢失任何页面状态,请将所有集合中的当前页面附加到链接:
Paginator::setPageName('page_a');
$collection_A->appends('page_b', Input::get('page_b',1))->links();
Paginator::setPageName('page_b');
$collection_B->appends('page_a', Input::get('page_a',1))->links();
【讨论】:
【参考方案4】:在 Laravel 5.2 中,使用 paginate()
时声明页面名称。
这是一个在一个页面上使用多个分页器的示例。
请务必为其他型号指定不同的$pageName
。
见方法\Illuminate\Database\Eloquent\Builder::paginate()
/**
* Get things by ownerId
*
* @param integer $ownerId The owner ID.
*
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator Returns a pagination instance.
*/
public function getThings($ownerId)
$builder = \App\Models\Things::where('ownerId', '=', (integer) abs($ownerId));
// dd([
// '__METHOD__' => __METHOD__,
// '__FILE__' => __FILE__,
// '__LINE__' => __LINE__,
// '$ownerId' => $ownerId,
// 'sql' => $builder->toSql(),
// '$builder' => $builder,
// 'paginate' => $builder->paginate($perPage = null, $columns = ['*'], $pageName = 'p', $page = null),
// ]);
return $builder->paginate($perPage = null, $columns = ['*'], $pageName = 'p', $page = null);
注意:$pageName = 'p'
【讨论】:
【参考方案5】:$publishedArticles = Article::paginate(10, ['*'], 'published');
$unpublishedArticles = Article::paginate(10, ['*'], 'unpublished');
第三个参数使用如下:
laravel/public/articles?published=3
laravel/public/articles?unpublished=1
【讨论】:
谢谢,在 Laravel 5.4 上工作得很好,但是如果你想让它们同时工作,你仍然需要附加其他页面。 这是 Laravel 5.4 的解决方案 非常好的解决方案,特别是在使用分页而不直接从相关模型的视图中准备的情况下,假设客户,模型有很多产品,@foreach ($customer->products()->paginate(10,['*'],'anotherPageParam') as $product)
然后对于链接,!! $customer->products()->paginate(10,['*'],'anotherPageParam')->links() !!
这比公认的答案更优雅、更干净,谢谢!
也适用于 laravel 8。谢谢【参考方案6】:
用途:
$var1 = DB1::orderBy('...')->paginate(5, ['*'], '1pagination');
$var2 = DB2::orderBy('...')->paginate(5, ['*'], '2pagination');
对于 Laravel 5.2
【讨论】:
重复答案。【参考方案7】:在 laravel 5.3 中(可能在其他 laravel 5 版本中工作),我这样使用:
$produk = Produk::paginate(5, ['*'], 'produk');
$region = Region::paginate(5, ['*'], 'region');
并在刀片模板中附加链接其他的电流以保持位置:
$produk->appends(['region' => $region->currentPage()])->links()
$region->appends(['produk' => $produk->currentPage()])->links()
【讨论】:
我可以确认这适用于 Laravel 5.8...我自己实现了它,谢谢 这也是 laravel 8 中的正确答案【参考方案8】:anonym 的答案可以扩展为在有相关模型的视图中非常方便。 在laravel-5.4测试:
假设我们有一个 CustomerController show.blade.php
的视图,并且我们使用以下方法将 Customer
模型传递给它:
```
return view(['customer' => \App\Customer::find($customerId)]);
``` 每个客户都有很多产品,并且有很多位置,我们想要列出他/她的产品和位置的分页,我们可以在视图中这样做:
@foreach($customer->products()->paginate(10,['*'],'productsPage') as $product)
html list
@endforeach
!! $customer->products()->paginate(10,['*'],'productsPage')->links() !!
@foreach($customer->locations()->paginate(10,['*'],'locationsPage') as $location)
HTML list
@endforeach
!! $customer->locations()->paginate(10,['*'],'locationsPage')->links() !!
【讨论】:
【参考方案9】:Laravel 5.7
Model->paginate(10, ['*'], 'paramName');
10 = Max items per page
['*'] = colums
paramName = pagination param name
Illuminate\Database\Eloquent\Builder
【讨论】:
【参考方案10】:这有点晚了,但它适用于 laravel 7.x
$messages = Message::where('status', 0)
->paginate(10, ['*'], 'p')
->appends(Arr::except(Request::query(), 'p'));
在你看来,example(inbox.blade.php)
$messages->links()
【讨论】:
【参考方案11】:在 Laravel 8 中工作,paginate
需要 4 个参数:
片段:(API Docs, Github)
public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
修改每个模型的第三个参数$pageName
,并为该分页器附加除$pageName
之外的所有查询参数应该可以工作:
FirstModel::query()
->paginate(null, ['*'], 'first_model')
->appends(request()->except('first_model'));
SecondModel::query()
->paginate(null, ['*'], 'second_model')
->appends(request()->except('second_model'));
注意,在此处使用->appends(...)
可确保该分页器的所有分页链接都将保留当前查询参数值。
例如,如果您在 URL ?first_model=2&second_model=3
上,first_model
分页器的链接将类似于:
?first_model=1&second_model=3
下一个:?first_model=3&second_model=3
【讨论】:
我们可以使用 ->withQueryString() 来代替 ->appends。像这样的 FirstModel::query() ->paginate(null, ['*'], 'first_model')->->withQueryString()。为我工作以上是关于Laravel 多页分页的主要内容,如果未能解决你的问题,请参考以下文章