Zend框架 - 何时使用视图脚本/局部视图 vs 视图助手

6
我正在为我们的应用程序创建一组显示对象库。它们以不同的视图呈现常见对象(用户、会话、消息等)的 HTML。所谓视图,是指对象可以以不同的标记语言返回不同的“缩放级别”。
一些显示对象包含其他显示对象来进行渲染,例如用户列表对象按照特定视图呈现用户对象(这个特定视图将它们作为列表项返回,以适合列表中)。
我试图将它们移动到 ZF 中正确的实现方式,但我无法确定它们是否应该全部成为视图助手,还是它们都是视图脚本/局部视图。
仅将它们设为视图脚本并使用 ->render() 渲染似乎有点不太好,因为我想传递给它们的任何信息或参数都必须分配给视图对象。
局部视图似乎更正确,但不确定在其中执行显示逻辑是否合适(如果将“showNotificationStatus”作为参数传递,则呈现此 span)。或者局部视图是否可以呈现其他局部视图(用户列表呈现用户对象)。
视图助手似乎可能是正确的方法,但我不知道是否过度使用了视图助手。每个对象都可以是一个视图助手,并接受一个 objectview 参数,以便知道要在哪个缩放级别/容器中呈现自己,或者每个 objectview 甚至可以是它自己的助手(因此没有大的 switch 语句在对象内部)。视图的一个好处是您可以传递参数,如果需要从该级别获取一些内容,则仍然可以访问视图上下文。
其中大多数将接受模型,其中一些需要一些额外的参数来知道要做什么(例如上面的 showNotificationStatus)。这个问题的正确工具是什么?
2个回答

15

局部视图的核心理念之一是要尽可能地实现可复用性,这也是它们拥有自己变量作用域的原因。我喜欢将局部视图用作包含少量HTML片段的简单容器,除了一些if()foreach()语句外,没有太多的逻辑。

如果需要处理严肃的逻辑问题,我会使用帮助器。帮助器应该负责处理逻辑并调用渲染方法。我知道在Rails世界中,帮助器倾向于封装一些小的逻辑,比如处理链接或图像标记的构建。这很好,但我认为在ZF中使它们更加复杂没有任何危害。我基本上用它们来将我的业务对象转换成视图。

我认为同时使用局部视图和帮助器的最佳方式是让帮助器设置数据,然后将其传递给局部视图。这样你的HTML代码就能保持非常易于维护(我猜每次有人输入echo "<a href='". $my_link . '"/>"时,都会有一只小猫死去)。

编辑(详细说明):

关于帮助器要记住的一件事是,它们可以像普通类一样使用构造函数带有参数并拥有私有成员。因此,当你实例化一个帮助器时,你可以传入业务对象,并且有多个方法通过局部视图来渲染HTML。

所以在我的视图中:

<?php $helper = $this->_helper->MyUserHelper($users); ?>
<ul>
  <?php $helper->user_list(); ?>
</ul> 

在这里,user_list() 方法返回一组带有所有正确数据的 <li> 元素。

我的辅助方法可能长这样:

class MyWidgetHelper 
{
  private $_widget;   

  public function __construct($users)
  {
     $this->_users = $users;
  }

  public function user_list()
  {
     // do any necessary logic here
     // then return the html that gets rendered. 
     // you can call a partial from here, and it just returns an HTML string.
     return $this->_view->partial('partials/_user_item.phtml', array('users' => $users)
  }
}

Bryan,我认为这是非常好的信息。你有可能详细解释一下吗?比如说你有一个业务对象,可以在不同的缩放级别(详细程度)下表示。你是否有一个帮助程序,根据传递的参数呈现不同的部分内容?还是有许多帮助程序和相应的部分内容?基本上,您是否正在查看通常的1对1关系?部分内容是否可以利用其他视图助手?(想象一个包含其中用户列表的对话。需要在对话部分中呈现用户。) - Bob Spryn
我在上面的回复中添加了一个示例。 在我的示例中,我使用帮助程序来控制部分文件,但我不知道为什么不能反过来做。 我只是更喜欢让我的HTML尽可能不包含PHP逻辑。 - Bryan M.
太棒了。非常感谢Bryan! - Bob Spryn
谢谢,这是我见过的关于这个问题最好的分解和解释。我刚刚在处理这个问题,想到了同样的解决方案,现在感觉很有信心能够正确地使用部分和视图助手。 - AndreLiem
我同意@AndreLiem的观点,这是一个清晰的解释,也是我计划做同样事情的方式。感谢您提供了一个好答案。我给你+1。 - Andy
FYI 刚刚看到这个链接:https://dev59.com/MlfUa4cB1Zd3GeqPI4vm 它建议使用 $this->render() 而不是 $this->partial(),主要是因为在处理 partials 时会产生堆栈问题(视图被复制,而 VH 只是一个类)。 - Andy

0

Helpers 用于逻辑(例如将对象转换为数组),partials 用于装饰逻辑(将递归数组显示为 <ul> 树形结构)。

记住,您也可以使用 $this->render('anyfile.ext')include()


有一件事让我感到模糊的是,ZF附带了一些助手,可以根据提供的数据创建HTML元素。请参见http://zendframework.com/manual/1.10/en/zend.view.helpers.html上的所有表单助手。 例如,formCheckbox会创建一个复选框,并使用您传递给它的数据。 - Bob Spryn
1
具有不同HTML输出的辅助函数,请使用setPartial()。当运行部分过于昂贵(或者您确定它的输出每次都相同)时,最好只是在辅助函数中硬编码HTML。如果未设置部分,则只需实现setPartial()并回退到默认标记即可。 - takeshin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接