菜单构建模式


9

当菜单不用于路由时,我难以理解菜单的活动状态处理。

我来自Drupal,菜单系统也处理路由。因此,设置活动状态和活动尾随状态由路由处理(也充当菜单渲染系统)。

现在,许多PHP框架都有处理路由的Router类。这似乎是一个很好的分隔,因为菜单不应该知道POST ||。选项|| ... 要求。

但是在编写前端时,我发现自己很难对菜单进行编码。或者将所有内容存储在数据库中,然后将这些值传递给视图。我不喜欢这种方法的原因是您正在创建已经在Router中写过的内容的副本,但是现在使用Menu类。

一个例子:

Route::get('/somewhere','routename.somewhere','showStuffController');
Route::post('/somewhere','routename.somewhere','saveStuffController');

Menu::add('label.somewhere','routename.somewhere');

您在这里分离关注点,所以很好。但是Menu在很大程度上取决于Route来设置其活动状态。菜单还必须了解有关设置活动跟踪的层次结构。

因此,是的,设置活动路径和活动状态类实际上是一种视图。但是有

if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; }

您的所有观点看来都是愚蠢的。然后添加所有那些烦人的活动提示if,这确实是个肿。我知道,在视图渲染之前处理该问题并将active-trail标志设置为true似乎很丑陋(foreach遍历所有子级,遍历所有子级,...)

我的问题是:

有没有一种模式或聪明的方法来使这种清洁剂变得更好,更好……?一个人应该如何应对主动式“问题”?

我当时想渲染子级->父级。因此,从最深层次的广告开始,然后逐步发展。但是,孩子对父母一无所知,但父母对孩子一无所知(似乎很奇怪)。

Answers:


1

当菜单不用于路由时

我会说路由可以用于菜单。


正如您已经指出的那样,路由器将是连接的好地方。我认为使用一个钩子来评估每个请求中当前页面的菜单元并不难看。

如果使视图负责跟踪活动状态,则不会分开关注点。视图应做其应做的一切-但也不必管理菜单状态。菜单元数据通常在整个应用程序范围内都是相同的,并且您只需要路由就可以定位自己并呈现菜单。

根据您的路由器和需求,一个简单的函数或类需要一些静态菜单元数据,并且当前路由足以提供您以后需要的所有信息。

菜单元本身不一定必须是对象。在大多数情况下,没有方法的简单键值数据结构就足够了。

该挂钩可能会创建一个状态对象,该状态对象具有与菜单相关的一些常用功能,例如面包屑,深度,父页面或当前页面,并在您的http请求的上下文中使该对象已知。您可能会遇到很多不同的可能性-但总的来说,这是关于收集,准备必要的数据并将其传递给知道如何处理的信息。

这种方法可根据您的需求进行扩展,并具有一些优点:

  1. 您的数据库不需要处理可以在运行时以低成本提供的数据
  2. 您将菜单(元数据)放在一个可以维护的地方
  3. 如果您希望菜单完全依赖1:1的路线,则可以通过动态提供菜单元来实现
  4. 如果内容增加(因此菜单也增加),则可以将此数据移至会话中,该会话可能会写入快速键值存储中
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.