在本系列中,您一直在向您的演示应用程序添加新的链接,以测试Laravel Eloquent的几个功能。您可能注意到主索引页面每次添加新链接时都会变得更长,因为在应用程序中显示的链接数量没有限制。
在本系列中,您将学习如何使用limit()
方法限制 Laravel Eloquent 查询中的结果数量,以及如何使用SimplePaginate()
方法页面化结果。
限制 Query 结果
要开始,您将更新您的主要应用路线(/
),以限制在您的索引页面上列出的链接的数量。
首先,在您的代码编辑器中打开您的 Web 路由文件:
1routes/web.php
然后,找到主要路线定义:
1[label routes/web.php]
2Route::get('/', function () {
3 $links = Link::all()->sortDesc();
4 return view('index', [
5 'links' => $links,
6 'lists' => LinkList::all()
7 ]);
8});
突出的行显示了通过链接
模型all()
方法获取数据库中的所有链接的查询,正如本系列的上一部分所解释的那样,该方法是从模型
类继承的,并返回一组包含与该模型相关联的所有数据库记录的集合。
现在,您将更改突出的行,以使用数据库查询排序方法 orderBy()
,该方法在数据库级别上排序查询结果,而不是简单地通过 all()
方法将返回为 Eloquent Collection 的整个行组重新排序。
用以下代码更换您的主要路线,以便您方便地进行更改:
1[label routes/web.php]
2Route::get('/', function () {
3 $links = Link::orderBy('created_at', 'desc')->limit(4)->get();
4
5 return view('index', [
6 'links' => $links,
7 'lists' => LinkList::all()
8 ]);
9});
更新后的代码现在会将最新的 4 个链接添加到数据库中,无论哪个列表。
接下来,您将学习如何页面化结果,以确保所有链接仍然可访问,即使它们不会同时在单个页面上加载。
搜索结果 查询结果
您的索引页面现在限制了列出的链接的数量,以便您的页面不会被内容过载,并在更短的时间内进行渲染。虽然这种解决方案在许多情况下工作得很好,但您需要确保访问者仍然可以访问旧链接,这些链接默认不见。
Laravel Eloquent 具有原生方法,可方便对数据库查询结果实施页面化,而paginate()
和simplePaginate()
方法则负责生成页面化链接,处理 HTTP 参数来识别当前所请求的页面,并对数据库进行查询以获得预期结果的正确限制和抵消,这取决于您想要列出的页面上记录的数量。
现在,您将更新routes/web.php
中的 Eloquent 查询以使用simplePaginate()
方法,该方法会生成具有 以前和 接下来的链接的基本导航。
在代码编辑器中打开 routes/web.php
文件,开始更新 /
路线,用 simplePaginate()
代替 limit(4)->get()
方法调用:
1[label routes/web.php]
2...
3Route::get('/', function () {
4 $links = Link::orderBy('created_at', 'desc')->simplePaginate(4);
5
6 return view('index', [
7 'links' => $links,
8 'lists' => LinkList::all()
9 ]);
10});
11...
接下来,在相同的文件中找到/{slug}
路径定义,并用simplePaginate()
方法替换get()
方法。
1[label routes/web.php]
2...
3Route::get('/{slug}', function ($slug) {
4 $list = LinkList::where('slug', $slug)->first();
5 if (!$list) {
6 abort(404);
7 }
8
9 return view('index', [
10 'list' => $list,
11 'links' => $list->links()->orderBy('created_at', 'desc')->simplePaginate(4),
12 'lists' => LinkList::all()
13 ]);
14})->name('link-list');
15...
这就是你完成后完成的 routes/web.php
文件的样子。
1[label routes/web.php]
2<?php
3
4use Illuminate\Support\Facades\Route;
5use App\Models\Link;
6use App\Models\LinkList;
7
8/*
9|--------------------------------------------------------------------------
10| Web Routes
11|--------------------------------------------------------------------------
12|
13| Here is where you can register web routes for your application. These
14| routes are loaded by the RouteServiceProvider within a group which
15| contains the "web" middleware group. Now create something great!
16|
17*/
18
19Route::get('/', function () {
20 $links = Link::orderBy('created_at', 'desc')->simplePaginate(4);
21
22 return view('index', [
23 'links' => $links,
24 'lists' => LinkList::all()
25 ]);
26});
27
28Route::get('/{slug}', function ($slug) {
29 $list = LinkList::where('slug', $slug)->first();
30 if (!$list) {
31 abort(404);
32 }
33
34 return view('index', [
35 'list' => $list,
36 'links' => $list->links()->orderBy('created_at', 'desc')->simplePaginate(4),
37 'lists' => LinkList::all()
38 ]);
39})->name('link-list');
完成后保存文件。
数据库查询现在已更新,但您仍然需要更新前端视图以包含将导航栏渲染的代码. 由 simplePaginate()
获得的 Eloquent 集合包含一种称为 links()
的方法,可以从前端视图调用以输出必要的 HTML 代码,该代码将基于页面的 Eloquent 查询进行导航。
您还可以使用页面的 Eloquent 集合中的链接()
方法访问固有的 Paginator 对象,该对象提供了几种 有用的方法来获取有关内容的信息,例如当前页面,以及是否有多个内容页面。
在您的代码编辑器中打开resources/views/index.blade.php
应用程序视图:
1resources/views/index.blade.php
查找标记为链接
的部分的尽头,其中包含链接渲染的前方
循环,在该部分之后并在该页面上最后的</div>
标签之前放置以下代码:
1[label resources/views/index.blade.php]
2 @if ($links->links()->paginator->hasPages())
3 <div class="mt-4 p-4 box has-text-centered">
4 {{ $links->links() }}
5 </div>
6 @endif
此代码通过访问 Paginator 对象并调用 hasPages()
方法来检查结果的多个页面是否存在.当该方法返回 true 时,页面会返回一个新的 div
元素,并调用 links()
方法来打印相关 Eloquent 查询的导航链接。
以下是更新后的index.blade.php页面,一旦完成,它将是这样的:
1[label resources/views/index.blade.php]
2<!DOCTYPE html>
3<html>
4<head>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7 <title>My Awesome Links</title>
8 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
9
10 <style>
11 html {
12 background: url("https://i.imgur.com/BWIdYTM.jpeg") no-repeat center center fixed;
13 -webkit-background-size: cover;
14 -moz-background-size: cover;
15 -o-background-size: cover;
16 background-size: cover;
17 }
18
19 div.link h3 {
20 font-size: large;
21 }
22
23 div.link p {
24 font-size: small;
25 color: #718096;
26 }
27 </style>
28</head>
29<body>
30<section class="section">
31 <div class="container">
32 <h1 class="title">
33 @if (isset($list))
34 {{ $list->title }}
35 @else
36 Check out my awesome links
37 @endif
38 </h1>
39 <p class="subtitle">
40 @foreach ($lists as $list)<a href="{{ route('link-list', $list->slug) }}" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }} ({{ $list->links()->count() }})</a> @endforeach
41 </p>
42
43 <section class="links">
44 @foreach ($links as $link)
45 <div class="box link">
46 <h3><a href="{{ $link->url }}" target="_blank" title="Visit Link: {{ $link->url }}">{{ $link->description }}</a></h3>
47 <p>{{$link->url}}</p>
48 <p class="mt-2"><a href="{{ route('link-list', $link->link_list->slug) }}" title="{{ $link->link_list->title }}" class="tag is-info">{{ $link->link_list->title }}</a></p>
49 </div>
50 @endforeach
51 </section>
52
53 @if ($links->links()->paginator->hasPages())
54 <div class="mt-4 p-4 box has-text-centered">
55 {{ $links->links() }}
56 </div>
57 @endif
58 </div>
59</section>
60</body>
61</html>
如果你回到你的浏览器窗口,现在重新加载应用程序页面,你会注意到一个新的导航栏,每次你有超过4个链接在一般列表或任何单独的链接列表页面。
有了功能页面化,您可以扩展您的内容,同时确保旧项目仍然可供用户和搜索引擎访问. 在您只需要基于某些标准的固定数量的结果的情况下,如果页面化不必要,您可以使用limit()
方法来简化查询并保证有限的结果集。