Laravel 视图:视图合成器
问题
我希望每次呈现视图时都能将某些数据绑定到视图,并将逻辑组织到一个统一的位置中,在 Laravel 中有什么办法可做到么?
回答
你可以使用视图合成器,视图合成器是在呈现视图时调用的回调或类方法。如果每次呈现视图时都希望将某些数据绑定到视图,视图合成器可以帮助我们将该逻辑组织到一个统一的位置中。
下面我们以创建一个 ProfileComposer
视图合成器为例,讲解如何创建和使用视图合成器,该视图合成器将用户计数绑定到视图。
创建视图合成器
默认情况下,Laravel 没有存放视图合成器的目录,我们需要新建目录,本例中,我们将在 app/Http
目录下创建 View/Composers
子目录,并在该子目录下创建一个名为 ProfileComposer.php
的文件,内容如下:
app\Http\View\Composers\ProfileComposer.php
<?php
namespace App\Http\View\Composers;
use Illuminate\View\View;
use App\Repositories\UserRepository;
class ProfileComposer
{
/**
* The user repository implementation.
*
* @var UserRepository
*/
protected $users;
/**
* Create a new profile composer.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
// Dependencies automatically resolved by service container...
$this->users = $users;
}
/**
* Bind data to the view.
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('count', $this->users->count());
}
}
在 ProfileComposer
类中,我们定义了一个 compose
方法,并传入一个 Illuminate\View\View
实例。该方法会在视图渲染之前被调用,我们可以使用 $view
的 with
方法将数据绑定到视图。
因为所有的视图合成器都会通过 服务容器 进行解析,所以我们可以在视图合成器的构造函数中类型提示需要注入的依赖项。
注册视图合成器
创建好视图合成器之后,我们还必须注册它,这样才能在每次渲染视图时都会执行 ProfileComposer@compose
方法。
下面,我们在 app\Providers
目录中创建一个 ViewServiceProvider
服务提供商 来注册视图合成器。
app\Providers\ViewServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function boot()
{
// Using class based composers...
View::composer(
'profile', 'App\Http\View\Composers\ProfileComposer'
);
// Using Closure based composers...
View::composer('dashboard', function ($view) {
//
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
我们在 ViewServiceProvider
服务提供器的 boot
方法中,用 View::composer()
方法注册视图合成器,该方法接受的第一参数可以是一个视图名(比如我们这里指定的是 profile
),也可以是包含一组视图的数组:
View::composer(
['profile', 'dashboard'],
'App\Http\View\Composers\MyViewComposer'
);
你甚至可以使用通配符 *
,表示将一个视图合成器添加到所有视图:
View::composer('*', function ($view) {
//
});
第二个参数可以是视图合成器的完全限定类名,也可以是一个闭包函数。
然后将这个新建的服务提供器添加到配置文件 config/app.php
的 providers
数组中:
'providers' => [
// 省略
App\Providers\ViewServiceProvider::class,
],
至此,我们就完成了一个视图合成器的创建、注册工作。