引言
這又是一個深入laravel執行方式的問題,面對數百張頁面,不可能所有的簡單的頁面 複雜的頁面都繼承了某些公用的layout資料。那麼如何做到給所有檢視都追加公共資料呢? 本文就來說一說。
學習時間比如文件中所說,可以用view物件的share方法分享全域性通用資料。程式碼像下面這樣:
View::share('data', [1, 2, 3]);
如果僅是指定控制器,或者路由的頁面才會追加公用資料,可以在宣告控制器的基類, 並在基類內注入公用資料。
class BaseController extends Controller{ public function __construct() { $user = User::all(); View::share('user', $user); // 共享資料 }}
在需要使用公用資料的控制上,使其繼承BaseController就可以了。
如果在某個應用的整個生命週期,你需要對所有的請求都要追加公用資料,那麼可以這應用載入之前, 就將資料暴露出來。
App::before(function($request){ View::share('user', User::all());});
或者我們直接在路由階段進行注入:
Route::filter('user-filter', function() { View::share('user', User::all());});
其中 user-filter 是正則表示式,支援篩選出有效的路由地址並進行使能。本身呼叫的方法是固定的。
其實為了將功能獨立出來,我們推薦使用中介軟體。因為中介軟體作為可插拔的元件, 功能獨立,完全不影響程式的上下文結構,不會造成執行上的困擾。
首先建立一箇中間件如下:
class SomeMiddleware { public function handle($request) { View::share('user', auth()->user()); }}
然後在規則內定義引用該中介軟體。
Route::group(['middleware' => 'SomeMiddleware'], function(){ // 路由});
深入一步我們說laravel具有極大的靈活性,因此,共享資料的操作,我們嘗試了應用啟動之初, 在路由過濾器內,在路由中介軟體內,在控制器基類內,都可以實現。
其實,在沒有達到檢視view之前,我們都有機會全域性操作公用資料。我們接著在 ViewComposerServiceProvider 伺服器提供者中解決這個問題。
namespace App\\Providers;use Illuminate\\Support\\ServiceProvider;class ViewComposerServiceProvider extends ServiceProvider { public function boot() { view()->composer("ViewName","App\\Http\\ViewComposers\\TestViewComposer"); }}
上述程式碼中,有兩個地方需要注意,一個是 composer 方法的兩個引數,一個是 ViewName,如果要對所有的檢視起作用, 那麼就填寫星號萬用字元。如果是單個檢視,則手動列出。
接下來實現第二個引數類:
namespace App\\Http\\ViewComposers;use Illuminate\\Contracts\\View\\View;class TestViewComposer { public function compose(View $view) { $view->with('ViewComposerTestVariable', "Calling with View Composer Provider"); }}
上述 TestViewComposer 類定義了變數以及值,就可以在檢視內使用了。比如有一個檢視檔案 ViewName.blade.php , 寫入簡單的內容:
Here you are... {{$ViewComposerTestVariable}}
那麼經過訪問後,變數就會正確地引用了。
準備完畢後,記得在 config/app.php 內註冊此類。
再說一種方式,如果全域性通用的公用資料,不區分任意路由,那麼可以在 AppServiceProvider 內註冊:
public function boot() { view()->share('data', [1, 2, 3]);}
寫在最後
本文通過多種方式在整個laravel的宣告週期流程內實現了對公用資料的暴露的需求, 解決問題的途徑很多很靈活,在實際中可以根據需要進行篩選。重要的掌握實現的思路和方法。
Happy coding :-)