【问题标题】:Dynamic layouts in CakePHPCakePHP 中的动态布局
【发布时间】:2019-06-11 15:05:14
【问题描述】:

很抱歉问题的标题,但我找不到更合适的表达方式。

我目前正在构建一个基于 CakePHP 的网站,但我不太确定如何解决以下问题。该网站看起来类似于以下样机:

.

灰色区域是布局的一部分,因为它们的内容在视图之间不会改变。在侧边栏中,我有一组链接到多个模型的广告。我需要控制器逻辑来确定与广告关联的图片。此外,广告列表需要是动态的。我应该把构建侧边栏的逻辑放在哪里?

我想过:

  • 将逻辑放入AppController (beforeFilter / afterFilter) - 问题是我无法使用我需要的控制器逻辑(其他控制器继承自AppController,我不确定如何在那里使用它们)。
  • 制作组件 - 是否可以构建依赖控制器的组件?
  • 在所有呈现视图的控制器中复制侧边栏代码 - 这对我来说似乎有点愚蠢。

蛋糕的方式是什么?


更新

经过一些阅读和实验,我已经开始重构大部分内容了。

通过在模型中移动构建广告的逻辑(删除检索图片的组件)而不使用requestAction,我获得了最佳性能。它几乎快了三倍,而且代码看起来好多了。

【问题讨论】:

    标签: model-view-controller cakephp layout


    【解决方案1】:

    如果结果是可缓存的,我猜答案是requestAction

    http://book.cakephp.org/view/434/requestAction

    【讨论】:

    • 感谢您的建议!我目前已经以这种方式实现了它,但是结果不可缓存,并且在调用 requestAction 时似乎涉及很多开销。如果您有任何其他想法,请分享:)。
    【解决方案2】:

    我为数据驱动的导航做了类似的事情。我把我的逻辑放在AppController::beforeRender 中并且没有遇到任何问题。我不确定我是否理解您对控制器继承的担忧。我通过以下方式检索我的菜单:

    $menus = $this->NavMenuItem->groupByMenu();
    $this->set( compact( 'menus' ) );
    

    然后我创建了一个呈现菜单的元素。它由布局通过以下方式执行:

    <?php echo $this->element( 'navigation', array( 'id' => 'secondary', 'menu' => $menus['SECONDARY'] ) ) ?>
    

    如果这没有帮助,也许您可​​以在评论中进一步解释您的控制器继承问题。

    【讨论】:

    • 感谢您的回答!我已经阅读了你关于这个主题的博客文章(使用谷歌找到它:),但我无法让它工作。问题是,当我从 AppController::beforeRender 方法调用 $this-&gt;Sidebar-&gt;build() 时,我得到一个 SQL 错误。它将方法名称解释为查询('build' 附近的语法错误)。我已将侧边栏控制器添加到使用数组中,就像您对菜单所做的那样,但我似乎仍然无法访问控制器方法 - 我想我正在使用模型对象。我认为这是一个继承问题——不能从父类调用子类的方法。
    • 您的AppController 使用您的侧边栏模型吗?例如public $uses = array( 'Sidebar' ); 语法错误听起来不像是 SQL,因为“构建”不是 SQL 的一部分,而是方法调用。
    • 是的,它在 $uses 数组中,我在之前的评论中提到过。我附上了代码i49.tinypic.com/210c41t.jpg 和错误i47.tinypic.com/111pdv4.jpg 的截图。
    • 所以我掩饰了您对build() 方法的使用。我熟悉 Rails 中的那个方法,但我不知道它存在于 CakePHP 中。还是您的Sidebarhits 模型(或AppModel)上的自定义方法?
    • 这是我在 Sidebarhits controller 中使用的自定义方法,用于获取我需要的广告。
    【解决方案3】:

    可以这样实现:

    1. 创建一个有助于广告块布局的元素
    2. 创建一个或多个控制器来生成渲染块所需的数据
    3. 使用 requestAction 将数据从模型中取出并放入元素中。

    查看蛋糕书,有一个元素示例,其中来自帖子模型的数据用于显示前/最新的 5 个帖子。我觉得你的要求和它很相似。

    【讨论】:

    • 我同意.. 最好创建一个元素,然后从元素内调用请求操作。从长远来看,这种方式可以在需要时缓存整个元素(以减少页面加载时间)。
    【解决方案4】:

    亚历克斯,

    您收到 SQL 错误,因为 build() 函数必须在 Sidebar 模型中,而不是控制器中。此外,您不一定需要使用 $user = array('Sidebar');你可以在你的所有模型中调用侧边栏:

    $Sidebar = ClassRegistry::init('Sidebar'); 然后是$Sidebar-&gt;find();$Sidebar-&gt;build(); 等。

    或者,如果你只需要从 Sidebar 模型中调用 build() 函数,你可以这样做:

      $sidebar = ClassRegistry::init('Sidebar')->build();
      $this->set('sidebar', $sidebar);
    

    干杯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多