3

我正在使用 Yii 框架来开发一个使用 2 列布局的站点。一栏是实际内容,而另一栏是带有站点链接的菜单,有关登录用户的一些信息以及最新帖子的列表。该菜单出现在所有页面上,但没有与当前页面(或路线)相关的信息。

每次渲染菜单时,我都需要从数据库中检索最新帖子列表和用户相关数据。我不确定如何最好地呈现这个菜单,这样我就不会重复在网站上的每个操作中获取数据的代码。

我已经想到了一些方法,我想知道其中哪一种(如果有的话)是处理这种情况的正确方法。

  • 在方法中获取数据Controller::beforeRender,然后在部分视图中渲染菜单,该部分视图在CClipWidget块中显示数据。然后,在布局视图中,显示菜单应该位于的块。这种方法有效,但我觉得它很笨拙,因为beforeRender. 如果我添加了一个没有菜单的页面,我需要对此进行检查。另外,在阅读了 Yii 文档之后,我不明白是否beforeRender()也需要调用renderPartial(),或者只是调用render().

  • 保留菜单的部分视图并从布局视图中呈现它。菜单视图中的数据是从放置在其他地方(可能在模型中)的静态方法中获取的。这涉及编写很少的代码,但我不确定这是否是 MVC 范式的好习惯。在视图中获取数据让我有点畏缩,即使它只是调用一个静态函数。

  • 将菜单变成小部件。数据在run()方法中获取并从小部件视图中呈现。但是,使用小部件会带来一些额外的限制。如果我想使用在控制器中呈现最新帖子的视图,我会遇到问题。小部件无法使用renderPartial(),并且一直被迫使用render()。如果我弄清楚如何检查渲染视图(小部件或控制器)的内容并适当地调用render()或调用,我可以解决这个问题。renderPartial()此外,小部件视图必须与站点视图分开,但我可以通过指定完整的视图路径来解决这个问题,比如application.views.controller.view,尽管它可能很笨重。此外,我仍然不确定小部件是否应该自己获取数据库数据。

所有这些方法都有效,但它们都有一些问题。我确信许多网站都处于相同的情况,我想看看最好的选择是什么。

4

1 回答 1

1

您应该能够通过简单地缓存数据库结果(在内存或文件中,这取决于您和您的设置)来避免重新请求此数据的大部分性能损失。这是一个小而简单的例子:

$posts = Post::model()->cache(600)->with('comments')->findAll(array('blah=blahdyblah'));

这会将返回的数据缓存 10 分钟。

为了完整起见,这里再次提供 Yii 缓存指南的链接: 缓存指南

要在每个页面上实际获取这些数据,最好将代码放在自己的小部件中,并在布局文件中的某个位置调用它。

您列出的小部件限制可以处理:

  • 首先,当小部件呈现它时,它只会render(),但没有布局。在大多数情况下这很好,但如果你确实想要一个只有那个的页面,假设你想要一个真正的render(),那么就这样做,只需创建一个只调用该小部件的视图。

  • 其次,没有理由必须将小部件从您的应用程序中完全抽象出来,并且不使用它的数据 + 模型。是的,它们可以是“可插入的”,这是一个非常好的功能,但这并不意味着它们必须是,您只是使用它们来分隔代码。

  • 最后,如果您确实想使用小部件中的“一些”数据但不是全部,或者稍微更改它,那么您在小部件中使用的方法和视图应该使用足够的抽象来构建,以便您可以使用您需要的部分分别地。做到这一点的一个好方法是充分利用scopesActiveRecords、迷你视图文件,并将组件用于更大的非数据逻辑块。

当然,如果您确实在性能极限下运行并且需要将请求时间缩短千分之一秒,那么您应该研究视图缓存并使用视图的片段缓存

于 2012-08-10T09:15:14.290 回答