我需要一些反馈来确保我没有完全错过CakePHP/MVC的重点。
我正在CakePHP中设计一个mini-cms——本质上是一个相册。我希望在每个页面上都有一个标准的样板下拉菜单。当然,当用户删除和添加相册时,菜单需要是动态的。
我的目标:构建与View::actionRequest()
相反方向移动的东西(即,不是视图回调控制器,而是让控制器在渲染之前将设置变量推送到 View 类。我的理解是,View::requestAction()
不是很优雅,而且很慢。
这是我对包含菜单关键字的表的模型。 app/Model/ModelItem.php
class MenuItem extends AppModel {
public function buildMainMenu() {
return $this->find('all');
}
}
由于我到处都想要它,所以我把电话放在AppController
class AppController extends Controller {
public function beforeFilter() {
$this->loadModel('MenuItem');
$this->set('mainMenuItems',$this->MenuItem->buildMainMenu());
}
}
这是一个被转储到我的CSS默认布局顶部的元素 - 元素文件:app/View/Element/navigation.ctp
- 布局:app/View/Element/Layout/default.ctp
<ul id="navigation">
<?php
foreach($mainMenuItems as $item) {
echo "<li>".$item['MenuItem']['name']."</li>";
}
?>
</ul>
我最终得到了一个可爱的项目符号列表,其中包含表格中的所有项目。我完全搞砸了吗?我都错了吗?我不知道。
我认为你的方法没有任何问题。以下是一些注意事项,完全可选:
- 我会将获取代码的菜单从
beforeFilter()
移动到beforeRender()
。没有理由这么早这样做,你可能会在需要菜单之前抛出异常,或者你可能会将用户重定向到另一个页面。此外,您在那里有关于请求的更多信息,因此您可以执行诸如在菜单中突出显示当前页面/项目/用户之类的操作。 - 将元素渲染代码移动到某种 MenuHelper 中,这将使您的车床更清洁(例如
$this->Menu->render()
在布局中)。您还可以使用 HtmlHelper 通过蛋糕呈现您的项目,并让蛋糕负责标记的正确性。 - 如果将渲染移动到帮助程序中,请为整个事情实现某种缓存方案,以加快速度 - 如有必要。缓存是否可行,或者是否应该在控制器或帮助程序中执行,完全取决于你和你的应用:)
我想总体建议是尝试将功能与应用程序的其余部分隔离开来;它更易于阅读、维护和修改。
我会把它打包成一个元素,并在布局/视图中输出菜单时使用请求操作来获取数据:
/app/View/Elements/main_menu.ctp:
$mainMenuItems = $this->requestAction('/menu_items/buildMainMenu');
<ul id="navigation">
<?php
foreach($mainMenuItems as $item) {
echo "<li>".$item['MenuItem']['name']."</li>";
}
?>
</ul>
并将其包含在您的布局/视图中:
echo $this->Element('main_menu');
这样,如果你有一个不需要菜单的视图/布局(例如Ajax),你就不会浪费数据库查询。