微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Laravel:从模块扩展视图

如何解决Laravel:从模块扩展视图

我的 Laravel 应用中有一个模块(它也可以是一个 composer 包)。 该模块有一个视图合成器,它为所有视图设置一个数组,其中包含应包含在应用主导航中的路线。

作曲家看起来像这样:


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

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

解决方法

对于那些也遇到过这个问题的人: 我把我的撰写方法改成了这个

// 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-方法来自每个 ViewComposer 所继承的 BaseComposer-类。

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 将其设置为使用视图外观上的 ::share 方法作为空集合的所有视图。

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

由于此 $moduleDataBag 是一个集合,因此所有附加值都可以合并到其中,只要它们是数组即可。这是递归完成的,以便保留每个现有的键和值。

希望以后能帮到人。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?