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 多页分页的主要内容,如果未能解决你的问题,请参考以下文章

以多页分页打印所有数据

Laravel手动分页的方法

这个laravel手动分页很好用

Laravel 多页面视图和会话

Laravel 5.6,使多页注册并将输入数据保存到会话

使用Vue-CLI怎么实现多页分目录打包