问题描述
我的 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
是一个集合,因此所有附加值都可以合并到其中,只要它们是数组即可。这是递归完成的,以便保留每个现有的键和值。
希望以后能帮到人。