1

我的 Laravel 应用程序中有一个模块(它也可能是一个作曲家包)。这个模块有一个视图编辑器,它为所有包含应该包含在应用程序主导航中的路由的视图设置一个数组。

作曲家是这样的:


class ContactNavigationComposer
{
    /**
     * Bind data to the view.
     *
     * @param  \Illuminate\View\View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('contactNavigation', config('contact.navigation'));
    }
}

然后在应用程序的 mainNav 中,这个变量$contactNavigation被迭代以生成条目:

<ul>
# ...
    <li>
        <a 
            class="{{ (request()->is('navigations/areas')) ? 'active' : '' }}" 
            href="{{ route('areas.index') }}">
                Navigation Areas
        </a>
    </li>
    <li>
        <a 
            class="{{ (request()->is('languages')) ? 'active' : '' }}" 
            href="{{ route('languages.index') }}">
                Languages
        </a>
    </li>
    @foreach($contactNavigation as $text => $url)
        <li>
            <a 
                class="{{ (request()->is($url)) ? 'active' : '' }}" 
                href="{{ $url }}">
                    {{ $text }}
            </a>
        </li>
    @endforeach
</ul>

这工作得很好,但我想知道我是否可以以更动态的方式拥有这种行为,并让不同模块的作曲家使用相同的数组,例如$modules包含不同模块的导航条目(和其他东西)。这样我以后就不必在应用程序视图中添加模块扩展。所以我建议的解决方案是smth。像那样:

class ContactNavigationComposer
{
    /**
     * Bind data to the view.
     *
     * @param  \Illuminate\View\View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('modules.navigation.contact', config('contact.navigation'));
    }
}
<ul>
    # ...
    @if (isset($modules['navigation']))
        @foreach($modules['navigation'] as $moduleNavigation)
            @foreach($moduleNavigation as $text => $url)
                <li>
                    <a 
                        class="{{ (request()->is($url)) ? 'active' : '' }}" 
                        href="{{ $url }}">
                            {{ $text }}
                    </a>
                </li>
            @endforeach
        @endforeach
    @endif
</ul>

当然,使用点表示法,这个modules.navigation.contact-key 永远不会转换为视图变量,尤其是不能转换为数组。

有没有办法实现这样的目标?

4

1 回答 1

0

对于那些也遇到这个问题的人:我将我的 compose 方法更改为这个

// ViewComposer
class ContactNavigationComposer extends BaseComposer
{

    public function compose(View $view)
    {
        $moduleDataBag = $this->getModuleDataBag($view);

        $moduleData = $moduleDataBag->mergeRecursive([
            'contact' => [
                'navigation' => config('contact.navigation.entries')
            ]
        ]);

        $view->with('modules', $moduleData);
    }
}

getModuleDataBag-method 来自BaseComposer每个 ViewComposer 继承自的 -class 。

class BaseComposer
{
    protected function getModuleDataBag(View $view)
    {
        if (!array_key_exists(config('contact.view.dataKey'), $view->gatherData())) {
            ViewFacade::share(config('contact.view.dataKey'), collect([]));
        }

        return $view->gatherData()[config('contact.view.dataKey')];
    }
}

存储所有配置的键在(可发布的)配置中定义。这样,此设置对于周围应用程序的修改是灵活的。(这个包叫做contact,这就是为什么视图数据键在contact-config中。)如果没有找到预期的键,则BaseComposer使用View-facade上的-method将其设置为所有视图::share作为一个空集合。

每个 ViewComposer 总是getModuleDataBag首先调用 - 方法来接收可能已经由其他 ViewComposer 设置的当前数据。

由于这$moduleDataBag是一个集合,所有附加值只要是数组就可以合并。这是递归完成的,以便保留每个现有的键和值。

希望以后可以帮助别人。

于 2021-03-04T19:53:51.847 回答