Laravel Blade 如何将 $attributes 从控制器传递给组件

问题描述

我有一个包含 $attributes 的刀片组件;当组件从另一个刀片模板调用时,它将是一个属性包,但是当通过 view() 从控制器调用时,$attributes 是未定义的!如何将数据作为 $attributes 从控制器传递?

组件:sample

<div {{ $attributes->except('content') }}>{{ $content }}</div>

模板:效果很好。

...
<x-sample class="test" content="test"/>
...

控制器:错误未定义的变量 $attributes

$attributes = ['class' => 'test','content' => 'test'];
view('components.sample',$attributes)->render();
view('components.sample',['attributes' => $attributes])->render();
view('components.sample')->with($attributes)->render();

更新(解决方案):

它有效:

view('components.sample',[
    'prop1' => '...','prop2' => '...','attributes' => new ComponentAttributeBag(['attr1' => '...','attr2' => '...']),])->render();

解决方法

发生的事情是组件从视图继承变量,例如,如果您从主视图定义变量,它应该在该视图的组件中工作。然后,当您将视图包含到 about 页面时,变量将不会被识别,因为它们不是从 about 视图继承的。而在 Laravel 中,你不能直接将数据从控制器传递给组件。但是 Laravel 已经通过 View Composer 解决了这个问题。

因为我不喜欢太多的复杂性,尤其是提供者,所以我编辑了我的 AppServiceProvider,您可以创建自己的提供者。

YourServiceProvider 在我的例子中 AppServiceProvider 在 boot() 函数中,您可以使用三个选项之一。我推荐第三个,因为它很干净

public function boot()
    {
        // option1 -  Every single view
         View::share('shops',Shop::orderBy('name')->get());

        // option2 - Gradular views with wildcards
         View::composer(['client.*'],function ($view){
             $view->with('shops',Shop::orderBy('name')->get());
         });

        // option3 - Dedicated class

        View::composer(['client.includes.*','client.create-product','client.cart'],ShopsComposer::class);
         View::composer(['client.includes.*',CartComposer::class);
    }

如果使用第 3 种方法,则必须创建 ViewComposer

<?php

namespace App\Http\View\Composers;

use App\Models\CartItem;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;

class ShopsComposer
{
    public function compose(View $view){
        $shop = auth()->user()->shops->sortBy('name');
        $cartItem = new CartItem();
        $cartCount = 0;
        if (Session::has('cartId')) {
            $carts = Session::get('cartId');
            $cartItems = $cartItem->with('products')->where('cart_id','=',$carts->id)->get();
        foreach ($cartItems as $item) {
            $cartCount += $item->quantity;
            }
        } 
        $view->with('shopsComposer',$shop)->with('cartCount',$cartCount);
    }
}

您在那里定义的变量将可用于所有视图。包括组件。由于组件从视图文件继承变量。

很抱歉我不得不分享我的工作示例,因为我的时间不多了。如果我很好地理解了您的问题,我希望它会起作用。