【问题标题】:Laravel: extending view from moduleLaravel:从模块扩展视图
【发布时间】:2021-06-01 23:24:20
【问题描述】:

我的 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 永远不会被转换为视图变量,尤其是数组。

有什么方法可以实现这样的目标吗?

【问题讨论】:

    标签: php laravel view laravel-blade laravel-views


    【解决方案1】:

    对于那些也遇到此问题的人: 我把我的 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-方法来自 BaseComposer-class,每个 ViewComposer 都从该类继承。

    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,这就是为什么view data key在contact-config中。) 如果未找到预期的键,BaseComposer 使用 View-facade 上的 ::share-方法将其设置为所有视图作为空集合。

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

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

    希望以后能帮到别人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-28
      • 2015-02-26
      • 2020-04-25
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 2023-03-28
      相关资源
      最近更新 更多