在 Laravel (v8) 中访问顶级组件内的视图数据

Accessing view data inside top level component in Laravel (v8)

是否有一种实用的方法来访问更高级别组件上的视图数据?让我解释一下:

我有一个 基本布局,只有核心 HTML 标签
views/layouts/base.blade.php

<!DOCTYPE html>
<html >
    <head>
        <title>Page Title</title>
    </head>
    <body>
        {{ $slot }}
    </body>
</html>

A Main Layout 布局组件扩展了这个
views/layouts/main.blade.php

<x-base-layout>
    <x-header-main />
    {{ $slot }}
    <x-footer-main />
</x-base-layout>

两者都有组件 类 以便它们在默认 views/components 文件夹之外工作。

然后,我的主视图是这样设置的
views/home.blade.php

<x-main-layout>
    <h1>{{ $data['my_heading'] }}</h1>
</x-main-layout>

来自 HomeController
app/Http/Controllers/HomeController.php

<?php

namespace App\Http\Controllers;

class HomeController extends Controller
{
    public function index()
    {
        $data = { "my_heading" : "My Heading", "my_email" : "my@email.com" };

        return view('home')->with(compact('data'));
    }
}

最后,真正的问题。我的页脚主要组件是这样的
views/components/footer-main.blade.php

<footer>
    <p>{{ $data['my_email'] }}</p>
</footer>

但是,正如您想象的那样,它不起作用。我得到一个错误:

ErrorException Undefined variable: data (View: C:\my-project\resources\views\components\footer-main.blade.php)

完成这项工作的正确方法是什么?我知道我可能在这里遗漏了一些 Laravel 继承概念,但我还不明白。

所以,经过一番努力,我找到了使用 View Composers 的解决方案。我会描述我最终得到的结果,以防它对某人有所帮助。

Note: A component higher in the hierarchy, like the <x-footer-main /> on my example, it's a view, as much as the final one you're calling via your route/controller.

app\Providers

中创建了一个 ViewServiceProvider
<?php

namespace App\Providers;

use App\Http\View\Composers\DataComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        View::composer('*', DataComposer::class);
    }
}

将提供程序添加到 config 文件。 config/app.php

'providers' => [
    /*
                 * Application Service Providers...
    */
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    App\Providers\BroadcastServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
    App\Providers\ViewServiceProvider::class,

],

创建了 DataComposer class 和类似 app/Http/View/Composers/DataComposer.php

的文件夹结构
<?php

namespace App\Http\View\Composers;

use Illuminate\View\View;
use App\Models\Data;

class DataComposer
{
    protected $data;

    public function __construct()
    {
        // Dependencies are automatically resolved by the service container...
        $this->data = Data::all();
    }

    public function compose(View $view)
    {
        $view->with('data', $this->data);
    }
}

成功了!!!