前回、トップページにキャンペーン応募を促すメッセージを表示するというケースでDIの説明をしました。
今回、編集画面などすべてのページに前回のメッセージを表示するケースを想定してみました。
すべてのページにメッセージを表示するには、コントローラクラスの index メソッドに記述したコードをほかのメソッドにも記述することで実現できます。
しかし、それはあまりにも冗長です。
こういうときの解決方法として使えるのが、コンポーネントクラスです。
環境
今回の開発環境は以下の通りです。
- Laravel 8
- PHP 8
実装
artisanコマンドにてコンポーネントクラスを生成
コンポーネントクラスをコマンドで作成します。
$ php artisan make:component Campaign
Component created successfully.
下記の2つが作成されます。
app/View/Components/Campaign.php
resources/views/components/campaign.blade.php
make:component
コマンドは、コンポーネントクラスに加えて、コンポーネントのビューテンプレートも作成してくれるので便利です。
それぞれの生成後の中身をみていきます。
Campaign.php
の方は、render()
に view が指定されています。
このrender()
が呼ばれて描画されることになります。
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Campaign extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|string
*/
public function render()
{
return view('components.campaign');
}
}
blade ファイルの方は、下記になります。
<div>
<!-- Simplicity is the ultimate sophistication. - Leonardo da Vinci -->
</div>
これらは、app/View/Components
ディレクトリとresources/views/components
ディレクトリに配置されます。
これらのディレクトリのものは、Laravel が自動的に検知するためコンポーネント登録が必要ありません。
Componentクラスの実装
app/View/Components/Campaign.php
の実装をします。
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use App\Models\User;
use App\Services\CampaignService;
use Illuminate\Support\Facades\Auth;
class Campaign extends Component
{
public $massages;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(CampaignService $camp)
{
$this->massages = $camp->getCampaignMassage(Auth::user());
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|string
*/
public function render()
{
return view('components.campaign');
}
}
コントローラクラスの index メソッドに実装したものをコンストラクタに移動しただけです。 移動したコントローラクラスの index メソッドは下記になります。
public function index()
{
return view('welcome');
}
すごくスッキリしました。
Viewの実装
resources/views/components/campaign.blade.php
を実装します。
<div>
@foreach ($massages as $msg)
@auth
<a href="{{ route($msg[Camp::MSG_LINK]) }}" >{{$msg[Camp::MSG_BODY]}}</a>
@endauth
@endforeach
</div>
resources/views/welcome.blade.php
に記載したものを移動します。
$massages ですが、前回は index メソッドにview('welcome', compact('massages'));
と VIEW ヘルパーの第 2 引数に指定していました。
コンポーネントクラスの場合はその必要がなく、コンポーネントクラスのプロパティが呼ばれることになります。
コンポーネントクラスの呼び出し
resources/views/welcome.blade.php
からコンポーネントクラスを呼ぶことになります。
前回、実装した下記の部分をコンポーネントクラスを表すタグ<x-campaign />
にします。
@foreach ($massages as $msg)
@auth
<a href="{{ route($msg[Camp::MSG_LINK]) }}" >{{$msg[Camp::MSG_BODY]}}</a>
@endauth
@endforeach
タグは、<x-{クラス名} />
になります。クラス名は、アッパーキャメルケース(パスカルケース)ですが、ここでは単語の間をハイフンでつなぐケバブケースになります。
テスト
前回作成した機能テストを再実行します。
php artisan test tests/Feature/CampaignServiceTest.php
エラーがなければ合格です。ただし、かなり簡単なテストですので実際はテストケースを増やします。
まとめ
あとは、土台となるlayout.blade.php
に<x-campaign />
タグを記述することで、全画面にキャンペーンメッセージが表示されます。
さらに詳細な使い方は下記のコンポーネントのセクションをみてください。