如何将数据传递给Laravel 5中的所有视图?

时间:2015-02-19 14:11:08

标签: php laravel laravel-5

我想在Laravel 5应用程序的所有视图中访问一些默认数据。

我试图搜索它但只找到Laravel 4的结果。我已阅读文档“与所有视图共享数据”here但我无法理解该怎么做。下面的代码应该放在哪里?

View::share('data', [1, 2, 3]);

感谢您的帮助。

13 个答案:

答案 0 :(得分:171)

这个目标可以通过不同的方法实现,

<强> 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中处理User对象的方式

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。使用中间件

View::sharemiddleware

一起使用
Route::group(['middleware' => 'SomeMiddleware'], function(){
  // routes
});



class SomeMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

<强> 4。使用View Composer

View Composer还有助于以不同方式绑定特定数据。您可以直接将变量绑定到特定视图或所有视图。例如,您可以根据需要创建自己的目录来存储视图编辑器文件。并且这些视图通过Service提供的composer文件提供了与视图的交互。

查看composer方法可以使用不同的方式,第一个例子可以看起来很相似:

您可以创建一个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");
    }
}

<强>参考

Laravel Documentation

进一步澄清Laracast Episode

如果我身边还有不清楚的地方,请告诉我。

答案 1 :(得分:54)

您可以创建自己的service providerViewServiceProvider名称很常见),也可以使用现有的AppServiceProvider

在您选择的提供程序中,将代码放入引导方法中。

public function boot() {
    view()->share('data', [1, 2, 3]);
}

这样可以在所有视图中访问$data变量。

如果您想使用外观而不是帮助程序,请将view()->更改为View::,但不要忘记在文件顶部放置use View;

答案 2 :(得分:8)

我发现这是最简单的一个。创建新的提供程序并使用'*'通配符将其附加到所有视图。也适用于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()
    {
        //
    }
}

答案 3 :(得分:6)

最好的方法是使用View::share('var', $value);

分享变量

使用"*"进行撰写的问题:

考虑以下方法:

<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);

$viewFacrory->compose('*', GlobalComposer::class);

从示例刀片视图:

  @for($i = 0; $i<1000; $i++)
    @include('some_partial_view_to_display_i', ['toDisplay' => $i])
  @endfor

会发生什么?

  • 使用GlobalComposer类实例化 1000 App::make
  • 处理事件composing:some_partial_view_to_display_i 1000 次。
  • compose类中的GlobalComposer函数被调用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());
  }
}

<强>更新

如果您使用的是通过中间件管道计算的内容,则可以监听到正确的事件,或者将视图共享中间件放在管道的最后一端

答案 4 :(得分:3)

在文档中:

  

通常,您可以在服务中调用share方法   提供者的启动方法。您可以自由添加它们   AppServiceProvider或生成一个单独的服务提供者   它们。

我同意Marwelln的说法,只需将它放在AppServiceProvider的启动功能中:

public function boot() {
    View::share('youVarName', [1, 2, 3]);
}

我建议为变量使用特定名称,以避免与其他没有“全局”变量的混淆或错误。

答案 5 :(得分:3)

文档会听到https://laravel.com/docs/5.4/views#view-composers,但我会将其分解

  1. 在应用程序的根目录中查找 app \ Providers 目录并创建文件 ComposerServiceProvider.php ,然后将下面的文本复制并粘贴到其中并保存它。

    <?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()
        {
            //
        }
    }
    
  2. 从应用程序的根目录打开 Config / app.php 并查找文件中的Providers部分,然后复制并通过此'App \ Providers \ ComposerServiceProvider', 到数组。

  3. 通过这样做,我们创建了Composer服务提供程序。使用视图配置文件(如 http://yourdomain/something/profile )运行应用程序时,将调用服务提供程序 ComposerServiceProvider ,并实例化类App \ Http \ ViewComposers \ ProfileComposer方法Composer由于下面的代码在引导方法或函数内部。

     // Using class based composers...
     View::composer(
       'profile', 'App\Http\ViewComposers\ProfileComposer'
     );
    
    1. 如果刷新应用程序,则会出现错误,因为 App \ Http \ ViewComposers \ ProfileComposer 类尚不存在。现在让我们创建它。
    2. 转到目录路径app / Http

      • 创建名为 ViewComposers

      • 的目录
      • 创建文件 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'
      );
      

      // Using class based composers...
      View::composer(
          '*', 'App\Http\ViewComposers\ProfileComposer'
      );
      

答案 6 :(得分:1)

我认为最好的方法是使用View Composers。如果有人来到这里并希望找到如何使用View Composers的方式,请阅读我的回答=&gt; How to share a variable across all views?

答案 7 :(得分:1)

文档在这里https://laravel.com/docs/5.4/views#view-composers但我会将其分解 1.查找根目录中的目录提供程序,并创建包含内容的for ComposerServiceProvider.php

答案 8 :(得分:1)

在您的配置文件夹中,您可以创建一个php文件名,例如&#34; variable.php&#34;内容如下:

g0

现在在所有视图中,您可以使用<?php return [ 'versionNumber' => '122231', ];来调用此变量。

答案 9 :(得分:0)

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);

}

答案 10 :(得分:0)

1)在(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)在您的视图中

 {{ $var_messages }}

答案 11 :(得分:0)

您有两个选择:

1。通过Boot中的‍ App\Providers\AppServiceProvider函数共享:

public function boot()
{
  view()->share('key', 'value');
}

然后在任何视图文件中访问$key变量。

Note:请记住,您无法在此处访问当前的SessionAuthRoute数据。仅当您要共享静态数据时,此选项才有用。假设您要基于当前用户,路由或任何您将无法使用的自定义会话变量共享一些数据。

2。使用帮助程序类:

在应用程序中的任何位置创建一个帮助程序类,并将其注册到app.php文件夹中config文件的Alias数组中。

 'aliases' => [ 
   ...,
  'Helper' => App\HelperClass\Helper::class,
 ],

并在App文件夹的HelperClass文件夹中创建Helper.php

namespace App\HelperClass;
    
class Helper
{
    public static function Sample()
    {
        //Your Code Here
    }
}

并访问Helper::Sample()之类的任何地方。

您不会restricted在这里使用AuthRouteSession或任何其他类。

答案 12 :(得分:0)

例如,您可以将数据库中所有表的列表返回到Controller的所有视图 像这样:

public function __construct()
{
    $tables = DB::select('SHOW TABLES'); // returns an array of stdObjects
    view()->share('tables', $tables);
}