本文项目的GitHub地址为:GitHub地址,可参考。
前言
之前例子的页面中,无论点击“Users”还是“Tasks”,侧边栏相应的位置都未被选中,即无法直观地得知当前页面是点击那个侧边栏标签进入的。其中Bootstrap提供了css样式,可以显示选中,如:1
<li class="active"><a href="{{ url('/user') }}">Users</a></li>
但若将该以上语句写死,则无法动态切换,如选中“Tasks”时,就无法正常显示。因此,需要考虑动态显示的方案。
常见的处理方案可分为两种。
其一为动态生成网页的侧边栏,即根据配置及当前的选中,生成侧边栏、顶部栏,然后再和主体拼接得到完整的网页。可写个SideBar的类完成该操作,扩张性较好。
另外,可将当前的选中返回前台页面,然后前端通过逻辑处理选中,该方法实现上较简单,因此此处使用该方式。
Laravel中提供了中间件,用于处理一些HTTP请求、身份验证等功能,同时还有用于运行各种任务。
本章此需求的思路为:
解析URL中主机地址后的模块名
将该模块名返回到前端
因此,此处使用中间件实现该功能。
创建中间件
在Artisan命令行中创建中间件:1
php artisan make:middleware RequestRoute
在该中间件中处理请求的URL。
中间件的处理可在基本逻辑之前或之后,由于要在视图中显示请求URL后的模块名,故此处使用view的share方法,在填充view层数据之前,将该数据共享给view,具体可参照sharing data with all views。
该中间件参照代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<?php
namespace App\Http\Middleware;
use Closure;
class RequestRoute
{
    /**
     * process url for selected
     * this work must handle before fill view data
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // parse url
        preg_match('/^http:\/\/([\w.]+)\/([\w]+)/i', $request->url(), $matches);
        // add share view
        if(!empty($matches[2]))
        {
            view()->share('requestRoute',$matches[2]);
        }
        return $next($request);
    }
}
此处需使用share view实现该功能。其中尝试过先填充view,然后再获取response,再重新在获取到的content里面赋值,重新封装为response,该种方式有问题,具体原因不详。以上方式测试通过。
注册中间件
生成中间件之后,在app/Http/Kernel.php中注册注册中间件,如下所示:1
2
3
4
5
6
7protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'request.route' => \App\Http\Middleware\RequestRoute::class,
];
注册的中间件为request.route。
路由中添加中间件
注册之后,在路由中添加,对需要的部分路由添加该中间件,添加如下为例:1
2
3
4
5
6Route::group(['middleware' => ['web', 'request.route']], function () {
    Route::resource('task', 'TaskController');
    Route::resource('user', 'UserController');
    Route::auth();
});
同时添加web、request.route。
前端显示
最后,在前端选中。此处使用了Laravel的blade模板,程序示例为:1
2
3
4<ul class="nav nav-sidebar">
    <li @if(isset($requestRoute)) @if($requestRoute == 'user') class="active" @endif @endif><a href="{{ url('/user') }}">Users</a></li>
    <li @if(isset($requestRoute)) @if($requestRoute == 'task') class="active" @endif @endif><a href="{{ url('/task') }}">Tasks</a></li>
</ul>
如此,即可完成侧边栏选中。
总结
本文中使用中间件实现了侧边栏的选中,简单介绍了中间件的使用。
但本文方案也有不少缺陷,如严重依赖于主机名之后的模块名。