【问题标题】:Make variables available in the whole view (including @yields) using View composers使用 View composers 使变量在整个视图(包括@yields)中可用
【发布时间】:2014-12-24 10:31:15
【问题描述】:

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

app/controllers/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);
    }

}

app/controllers/DashboardController.php

class DashboardController extends BaseController{

    public function index(){

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

    }

}

App\Composers\BaseComposer.php

class BaseComposer{
    public function compose($view){

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

        $view->with($data);

    }
}

app/composers.php

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

app/views/layouts/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>

app/views/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 视图中出现 Undefined variable: user 异常。

如您所见,我正在使用我的 BaseController 来提供一些视图辅助方法,例如“setUpLayout”和“view”,它们都在运行 View::make()。因此,即使我使用作曲家在“layouts.master”视图中调用“with()”,“仪表板”视图也不会继承这些变量。我查看了源代码,而 Illuminate\View\View::with() 并没有做更多的事情,只是将数据附加到 $data 属性,所以看起来每个 View::make() 调用都是相互独立的.

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

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

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

这将起作用,但视图编辑器将为每个视图执行。所以想象一下,如果我的视图作曲家有一个数据库调用,那么 questy 将被执行的次数与我拥有的视图一样多,包括像我的“视图/电子邮件”文件夹这样的视图,我不需要调用作曲家......

我一直在考虑开始在我的 BaseController 的属性中定义我的视图变量,因为我在我的 DashboardController 中扩展它,所以我可以执行以下操作:

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

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

【问题讨论】:

    标签: laravel laravel-4 blade


    【解决方案1】:

    使用View::share() 而不是with

    class BaseComposer{
        public function compose($view){
    
            $data = array(
                'user' => \Auth::user()
            );
    
            View::share($data);
        }
    }
    

    关于您在dashboard.blade.php 中的评论,如果您始终在控制器中设置布局,则不需要@extends,最好只在一个地方定义布局。

    【讨论】:

    • 我认为是View::share :)
    【解决方案2】:

    变量不会传递到产生的部分,所以这就是扩展布局的视图没有获取变量的原因。但是,您不需要在作曲家中使用通配符将变量附加到每个视图,您可以指定希望作曲家附加到的视图数组。在您的情况下,它是布局视图和仪表板视图:

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

    您可以将需要$user 变量的任何其他视图添加到该数组。欲了解更多信息,您可以查看Laravel Docs

    【讨论】:

    • 谢谢,这个问题除了必须手动定义每个视图来组合之外,还在于组合器将被执行两次,如果你从它们进行数据库查询,这可能会导致一些麻烦。但是,我发现这在定义多个不会一起渲染的视图时非常有用。
    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2020-03-28
    相关资源
    最近更新 更多