1

我需要一些反馈来确保我没有完全错过 CakePHP/MVC 的要点。

我正在用 CakePHP 设计一个 mini-cms——本质上是一个相册。我希望在每一页上都有一个标准的样板下拉菜单。自然,当用户删除和添加相册时,菜单需要是动态的。

View::actionRequest()我的目标:构建与(即,不是视图回调控制器,而是让控制器在渲染之前将设置变量推送到视图类)相反方向移动的东西。我的理解是这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>

最后,我得到了一个可爱的、列表中所有项目的项目符号列表。我完全把这件事搞砸了吗?难道我都错了吗?我不知道。

4

2 回答 2

4

我认为您的方法没有任何问题。不过,这里有一些注释,完全可选:

  • 我会将获取代码的菜单从beforeFilter()移至beforeRender(). 没有理由这么早做,您可能会在需要菜单之前抛出异常,或者您可能会将用户重定向到另一个页面。此外,您可以在此处获得有关请求的更多信息,因此您可以执行诸如突出显示菜单中的当前页面/项目/用户之类的操作。
  • 将元素渲染代码移动到某种 MenuHelper 中,这将使您的布局更清晰(例如$this->Menu->render()在布局中)。您还可以使用 HtmlHelper 通过 cake 渲染您的项目,并让 cake 负责标记的正确性。
  • 如果您将渲染移到帮助程序中,请为整个事物实施某种缓存方案,以加快速度 - 如果有必要的话。缓存是否可能,或者您是否应该在控制器或助手中进行缓存完全取决于您和您的应用程序:)

我想总体建议是尝试将部分功能与应用程序的其余部分隔离开来;它更易于阅读、维护和修改。

于 2012-06-04T19:31:40.553 回答
0

当您在布局/视图中输出菜单时,我会将其打包成一个元素并使用请求操作来获取数据:

/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),您就不会浪费数据库查询。

于 2012-06-06T15:50:03.077 回答