使用View composers在整个视图中使变量可用(包括@yields)

时间:2014-10-28 20:47:45

标签: laravel laravel-4 blade

每次调用“views / layouts / master.blade.php”视图时,我都尝试使用$ user变量,所以这基本上是我当前的方法:

应用/控制器/ BaseController.php

class BaseController extends Controller{

    protected $layout = 'layouts.master';    

    protected function setupLayout(){
        if(!is_null($this->layout)){
            $this->layout = \View::make($this->layout);
        }
    }

    protected function view($path, $data = []){
        return $this->layout->content = \View::make($path, $data);
    }

}

应用/控制器/ DashboardController.php

class DashboardController extends BaseController{

    public function index(){

        return $this->view('dashboard');

    }

}

应用\作曲家\ BaseComposer.php

class BaseComposer{
    public function compose($view){

        $data = array(
            'user' => \Auth::user()
        );

        $view->with($data);

    }
}

应用/ composers.php

View::composer('layouts.master', 'App\Composers\BaseComposer');

应用/视图/布局/ master.blade.php

<html>
    <head>...</head>
    <body>
        <header>
            <button>{{{ $user->name }}}</button> //Button with the user name with a dropdown to log out (I'm using the $user variable from the composer)
        </header>
        <div id="content">
            @yield('content')
        </div>
    </body>
</html>

应用/视图/ dashboard.blade.php

@extends('layouts.master') //Should I put this eventhough I'm using controller templating? ($layout->content =  View::make(...))

@section('content')
    <p class="welcome">Welcome, {{{ $user->name }}}</p>
@stop

当我点击index()方法时,我的dashboard.blade.php视图中出现未定义变量:user 异常。

正如您所看到的,我正在使用我的BaseController来提供一些视图辅助方法,例如“setUpLayout”和“view”,它们都运行View :: make()。所以尽管我使用我的作曲家在我的“layouts.master”视图中调用“with()”,但“仪表板”视图将不会继承这些变量。我看一下源代码和Illuminate \ View \ View :: with()除了将数据附加到$ data属性之外没什么作用,所以看起来每个View :: make()调用彼此独立

所以这就是问题所在:如何在一次调用中定义视图所需的所有变量及其“@yields”?

我一直在研究,有些人建议像这样定义作曲家:

View::composer('*', 'App\Composers\BaseComposer');

这将有效,但View编辑器将针对每个视图执行。所以想象一下,如果我的View作曲家有一个DB调用,那么questy会被执行多次,就像我的“views / emails”文件夹一样,我不需要调用作曲家......

我一直在考虑开始在我的BaseController中的属性中定义我的视图变量,因为我在我的DashboardController中扩展它,我可以做类似的事情:

View::make('dashboard')->with($this->data);

但我喜欢拥有View作曲家的想法,他们只是没有像我期待的那样工作......也许我做错了,所以我很感激一些帮助。

2 个答案:

答案 0 :(得分:3)

使用View::share()代替with

class BaseComposer{
    public function compose($view){

        $data = array(
            'user' => \Auth::user()
        );

        View::share($data);
    }
}

关于您在dashboard.blade.php中的评论,如果您始终在控制器中设置布局,则不需要@extends,最佳做法是仅在一个位置定义布局。< / p>

答案 1 :(得分:0)

变量不会传递到已生成的部分,因此扩展布局的视图无法获取变量。但是,您不需要在编辑器中使用通配符将变量附加到每个视图,您可以指定希望将编辑器连接到的视图数组。在您的情况下,它是布局视图和仪表板视图:

View::composer(array('layouts.master', 'dashboard'), 'App\Composers\BaseComposer');

您可以将需要$user变量的任何其他视图添加到该数组。有关详细信息,请查看Laravel Docs