Laravel 中的 View Composer 該如何使用?

程式技術
sharkHead

假設有一個網頁,這個網頁有一個區塊是 menubar (選單欄)。menubar 上面有許多連結,這些連結都是儲存在資料表 categories 中。

因為這個 menubar 會固定在網頁上方,這代表幾乎所有的 blade 模板都會 include 這個 menubar 的 blade。那麼要如何將連結資料從資料表 categories 撈取出來之後,正確傳給 blade 並顯示呢?

土法煉鋼的作法。是在每個 Controller 裡的每個方法中寫上一段,去撈取資料表 categories 的所有資料。

$categories = Category::all();

然後再將變數 $categories 傳給 view。

return view('index', ['categories' => $categories]);

在每個 Controller 加上這一段,才能確保不論到哪一頁,menubar 都能確實收到變數 $categories

並正確顯示 menubar 上的所有連結。

但在每個 Controller 都加上這一段,工程師才沒這麼勤勞

官方其實還有另外一種方法 View Share,可以直接將參數傳給所有的 blade。

但是你很有可能遇到在 migration 時候噴錯,詳情請參考此連結,這時我們可以考慮使用 View Composer,將變數傳給指定的 blade 來使用。

首先新增檔案 app/Http/View/Composers/CategoryComposer.php

<?php

namespace App\Http\View\Composers;

use App\Models\Category;
use Illuminate\View\View;
use Cache;

class CategoryComposer
{
    // 設定用來依賴注入的變數
    protected $category;

    public function __construct(Category $category)
    {
        // 將 Category Model 依賴注入到 CategoryComposer
        $this->category = $category;
    }

    public function compose(View $view)
    {
    	// 取得所有分類並放入變數 categories
        $categories = this->category->all();
        // 將資料綁定至 blade 模板中
        $view->with('categories', $categories);
    }
}

上段程式碼中,依賴注入的對象是 Model,但官方文件在這裡選擇注入的對象是 Repository。一般來說大型專案會採用下面這種模式,以便於維護。

Model ←→ Repository ←→ Service  ←→ Controller

但這個模式並非強求,也有人覺得使用這種模式反而讓程式碼不易閱讀
所以只要專案組員們討論後有共識即可。

然後 app/Providers/ 底下新增一個檔案 ViewServiceProvider.php,內容可以參考官方文件

ViewServiceProvider.phpboot() 中新增一段程式碼。

use Illuminate\Support\Facades\View;
use App\Http\View\Composers\CategoryComposer;


public function boot()
{
	// 將分類的資料綁定至 View 中
	View::composer('layouts.menubar', CategoryComposer::class);
}

新增的 ViewServiceProvider.php 檔案,必須要在 config.php 中註冊才能使用。

'providers' => [
	//視圖合成器
	App\Providers\ViewServiceProvider::class,
]

這時,即使 Controller 沒有特地寫一段來傳遞參數 $categories

resources/views/layouts/menubar.blade.php 這個模板也能獲取 $categories 中的連結資料。

sharkHead
written by
sharkHead

後端打工仔,在下班後喜歡研究各種不同的技術。稍微擅長 PHP,並偶爾涉獵前端開發。個性就像動態語言般隨興,但渴望做事能像囉嗦的靜態語言那樣嚴謹。

0 則留言