我希望在我的Laravel 5应用程序中,所有视图都可以访问一些默认数据。
我尝试过搜索相关内容,但只找到了适用于Laravel 4的结果。我已经阅读了“共享所有视图的数据”这里的文档,但是我不知道该把以下代码放在哪里?
View::share('data', [1, 2, 3]);
谢谢你的帮助。
可以通过不同的方法实现这个目标,
1. 使用BaseController
我喜欢的设置方式是创建一个BaseController
类来继承Laravel自带的Controller
,并在其中设置各种全局配置。然后所有其他控制器都继承于BaseController
而不是Laravel的Controller。
class BaseController extends Controller
{
public function __construct()
{
//its just a dummy data object.
$user = User::all();
// Sharing is caring
View::share('user', $user);
}
}
2. 使用过滤器
如果你确定你需要为整个应用程序的每个请求设置视图,你也可以通过在请求之前运行的过滤器来完成这个操作。这就是我在 Laravel 中处理用户对象的方式。
App::before(function($request)
{
// Set up global user object for views
View::share('user', User::all());
});
或者
您可以定义自己的过滤器。
Route::filter('user-filter', function() {
View::share('user', User::all());
});
通过简单的过滤器调用它。
根据版本5.*更新
3. 使用中间件
使用middleware
与View::share
。
Route::group(['middleware' => 'SomeMiddleware'], function(){
// routes
});
class SomeMiddleware {
public function handle($request)
{
\View::share('user', auth()->user());
}
}
4. 使用视图构建器
视图构建器可以帮助以不同的方式将特定数据绑定到视图中。您可以直接将变量绑定到特定视图或所有视图。例如,您可以根据要求创建自己的目录来存储视图构建器文件。这些视图构造器文件通过服务提供程序与视图进行交互。
视图构建器方法可以以不同的方式使用,第一个示例可能看起来像:
您可以创建一个App\Http\ViewComposers
目录。
服务提供程序
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
public function boot() {
view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
}
}
在此之后,在"providers"部分下将该提供者添加到config/app.php中。
TestViewComposer
namespace App\Http\ViewComposers;
use Illuminate\Contracts\View\View;
class TestViewComposer {
public function compose(View $view) {
$view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
}
}
ViewName.blade.php
Here you are... {{$ViewComposerTestVariable}}
这种方法只能帮助特定的视图。但是,如果您想将ViewComposer应用于所有视图,则必须将此单一更改应用于ServiceProvider。
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
public function boot() {
view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
}
}
参考资料
如需进一步澄清,请参考Laracast第25集
如果我的解释还不够清楚,请告诉我。
register()
方法 - 这不是可选的。 - Jonathanparent::__construct();
。 - Safoor Safdar*
,那么就会出现这种情况。如果您不使用*
,那么应该没有问题。 - Syclone你可以创建自己的服务提供者(通常使用ViewServiceProvider
名称),或者使用现有的AppServiceProvider
。
在你选择的提供者中,将你的代码放入boot
方法中。
public function boot() {
view()->share('data', [1, 2, 3]);
}
这将在所有视图中使得$data
变量可访问。
如果你宁愿使用门面(facade)而非帮助函数(helper),请将view()->
更改为View::
,但不要忘记在文件顶部加上use View;
。
AppServiceProvider
里是可以的,但如果您有更多的内容,您应该考虑创建一个新的提供者。 - Marwellncomposer update
也无效。实际上,它根本没有触发 boot()
。我需要共享两个变量。 - itsazzad我发现这是最简单的方法。创建一个新的提供者,使用'*'
通配符将其附加到所有视图。在5.3中也适用:-)
<?php
namespace App\Providers;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
* @return void
*/
public function boot()
{
view()->composer('*', function ($view)
{
$user = request()->user();
$view->with('user', $user);
});
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
最好的方法是使用View::share('var', $value);
来共享变量。
使用"*"
组合视图时可能遇到的问题:
考虑以下方法:
<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);
$viewFacrory->compose('*', GlobalComposer::class);
来自一个示例的 Blade 视图:
@for($i = 0; $i<1000; $i++)
@include('some_partial_view_to_display_i', ['toDisplay' => $i])
@endfor
发生了什么?
App::make
实例化GlobalComposer
类1000次。composing:some_partial_view_to_display_i
1000次。GlobalComposer
类中的compose
函数1000次。但是,这里的部分视图some_partial_view_to_display_i
与由GlobalComposer
组合的变量无关,却严重增加了渲染时间。
最佳方法?
使用View::share
及其分组中间件。
Route::group(['middleware' => 'WebMiddleware'], function(){
// Web routes
});
Route::group(['prefix' => 'api'], function (){
});
class WebMiddleware {
public function handle($request)
{
\View::share('user', auth()->user());
}
}
更新
如果你正在使用在中间件管道上计算的内容,你可以简单地监听适当的事件或将视图共享中间件放置在管道的最底部。
AppServiceProvider
中使用Boot
函数分享:
2. 创建一个全新的服务提供者类:
public function boot()
{
view()->share('key', 'value');
}
在任何视图文件中,可以访问$key
变量。
注意
:请记住,您无法在此处访问当前的Session
、Auth
、Route
数据。这个选项只适用于共享静态数据。假设您想要根据当前用户、路由或任何自定义会话变量共享一些数据,使用此选项将无法实现。
2. 使用助手类:
在您的应用程序中的任何位置创建一个助手类,并在config
文件夹中的app.php
文件中的别名数组中注册它。
'aliases' => [
...,
'Helper' => App\HelperClass\Helper::class,
],
并在App文件夹内的HelperClass文件夹中创建Helper.php
文件:
namespace App\HelperClass;
class Helper
{
public static function Sample()
{
//Your Code Here
}
}
您可以随时在任何地方访问它,例如Helper::Sample()
。
在这里使用Auth
、Route
、Session
或任何其他类都不会受到限制。
public function boot() {
View::share('youVarName', [1, 2, 3]);
}
我建议为变量使用特定名称,以避免与其他非“全局”变量混淆或出错。
文档可以在这里找到 https://laravel.com/docs/5.4/views#view-composers,但我会对其进行简要解释。
Look for the directory app\Providers in the root directory of your application and create the file ComposerServiceProvider.php and copy and past the text below into it and save it.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function boot()
{
// Using class based composers...
View::composer(
'profile', 'App\Http\ViewComposers\ProfileComposer'
);
// Using Closure based composers...
View::composer('dashboard', function ($view) {
//
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
From the root of your application open Config/app.php and look for the Providers section in the file and copy and past this 'App\Providers\ComposerServiceProvider', to the array.
// Using class based composers...
View::composer(
'profile', 'App\Http\ViewComposers\ProfileComposer'
);
前往目录路径app/Http
Create the directory called ViewComposers
Create the file ProfileComposer.php.
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());
}
}
现在进入您的视图,或者在这种情况下是Profile.blade.php文件,并添加以下内容:
{{ $count }}
您需要在个人资料页面显示用户数量。为了在所有页面上显示数量,请更改
// Using class based composers...
View::composer(
'profile', 'App\Http\ViewComposers\ProfileComposer'
);
To
// Using class based composers...
View::composer(
'*', 'App\Http\ViewComposers\ProfileComposer'
);
1) In (app\Providers\AppServiceProvider.php)
// in boot function
view()->composer('*', function ($view) {
$data = User::messages();
$view->with('var_messages',$data);
});
2) 在您的用户模型中
public static function messages(){ // this is just example
$my_id = auth()->user()->id;
$data= Message::whereTo($my_id)->whereIs_read('0')->get();
return $data; // return is required
}
3) 在您的视角中
(涉及IT技术) {{ $var_messages }}
在你的config文件夹中,你可以创建一个名为"variable.php"的php文件,其内容如下:
<?php
return [
'versionNumber' => '122231',
];
config('variable.versionNumber')
Laravel 5.6 方法:https://laravel.com/docs/5.6/views#passing-data-to-views
例如,将模型集合共享到所有视图中(AppServiceProvider.php):
use Illuminate\Support\Facades\View;
use App\Product;
public function boot()
{
$products = Product::all();
View::share('products', $products);
}
*
时要小心,因为它会在每个包含的子视图、组件等中运行,所以你可能会运行数百个不必要的查询。最好的方法是使用基础视图,例如 layouts.app,然后根据需要向下传递数据。 - Andy Lobel