我来自CodeIgniter,它和其他MVC框架(特别是Zend)之间的术语重叠给了我某种心理障碍。
我希望我的用户访问http://mysite.com/do/this。
我理解“do”是Controller,而“this”是该Controller中的一个函数(井,方法)。
我的网站会有标题和侧边栏等常见元素;我知道那些会进入布局,这将被纳入最终输出。
我希望/ do / this页面显示三个可视化的信息块(我故意不使用“模块”这个词)。我们称之为BlockA,BlockB和BlockC。也许一个是“新事件”列表,另一个是“新帖子”列表,另一个是其他内容。随你。诀窍是,这些信息块也将显示在网站的其他页面上 - 比如http://mysite.com/did/that。
“do”和“do”控制器(以及“this”和“that”方法,显然)将以不同方式安排BlockA,BlockB和BlockC。每个控制器对于进入这些块的内容也会有不同的标准 - 一个可能是当前信息,而另一个可能是过去存档的信息。
我想确保未来的程序员可以轻松地改变BlockA,BlockB和/或BlockC的外观,而无需触摸填充其数据的代码或在每页上排列它们的代码。
所以我的一般感觉是BlockA,BlockB和BlockC需要在视图中定义它们的视觉布局 - 但是该视图不会与“do”或“did”控制器特别相关联。填充这些块的代码 - 也就是查询来自数据库的信息,选择要显示的位,以及什么 - 不应该完全驻留在那些控制器中。
我开始将逻辑 - 即将每个块中显示的内容 - 组装到模型中。我觉得我在正确的道路上,那里;因此,“do”和“did”控制器都可以通过模型召唤块创建代码。但是我如何(以及在哪里)抽象出这些块的可视元素,以便这两个控制器也可以共享可视元素?模型是否以某种方式加载View并将HTML输出到控制器(感觉不对)?或者控制器是否有办法运行模型,获取要显示的数据,然后以某种方式将其提供给公共/集中视图?
我知道如何在CodeIgniter中执行此操作。但是......使用Zend Framework,正确的架构是什么?我确信它与CodeIgniter的做法非常不同,我想开始用正确的架构来编写这个应用程序。
答案 0 :(得分:2)
一个小的命名事项:/:controller/:action/*
=> /do/this
= this
是action
(虽然也是控制器中的函数和方法,但操作是正确的名称)
你对我的阻止听起来像“部分观点”。有几种方法可以解决这个问题,根据视图的工作方式或他们需要了解的信息,您可以调整策略
如果您希望多个视图使用某些视图代码,则需要使用此方法。使用视图助手Zend_View_Helper::render
或Zend_View_Helper_Partial*
有两种不同的方法render($phtmlfile)
视图助手更有效,partial($phtmlfile, $module, $params)
视图助手克隆新视图,取消所有参数,以及设置你传入的那些。如何使用它们的一个例子:
情况下/ list.phtml:
<?php
$this->headTitle($this->title);
// works because our controller set our "cases" property in the view, render
// keeps our variables
echo $this->render("case/_caseListTable.phtml");
情况下/ view.phtml
<?php
$this->headTitle($case->title);
?><!--- some view code showing the case -->
<?php if ($cases = $case->getChildren()): ?>
<h3>Children</h3>
<?php echo $this->partial("case/_caseListTable.phtml", "default", array(
"cases"=>$cases,
)); ?>
<?php endif; ?>
情况下/ _caseListTable.phtml
// table header stuff
<?php foreach ($this->cases as $case): ?>
// table rows
<?php endforeach; ?>
// table footer stuff
有时控制器无法知道块中显示的信息是什么,为视图做准备会很愚蠢,此时你想制作自己的视图助手。您可以轻松地将它们添加到application.ini中的全局视图中:
resources.view.doctype = "XHTML1_STRICT"
resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/../library/My/View/Helper"
我倾向于将此方法用于需要控制器未提供的模型的额外信息,或视图的可重用格式代码块。一个简单的例子,来自我使用的项目:Olympic_View_Helper_Ontap
抓住生啤酒列表并呈现它:
class Olympic_View_Helper_Ontap extends Zend_View_Helper_Abstract {
public function Ontap()
{
$view = $this->view;
$box = Olympic_Db::getInstance()->getTable('box')->getBoxFromName('Draught-Beer');
if ($box) $menu = $box->getMenu(); else $menu = null;
$content = "";
if ($menu)
{
$content = "<h1>".$view->escape($menu->title)."</h1>";
$content .= "<ul>";
foreach($menu->getItems() as $item) {
$content .= "<li>".$view->escape($item->name)."</li>";
}
$content .= "</ul>";
}
return $content;
}
}
然后在我的布局中:
<?php echo $this->ontap(); ?>
你的View Helpers也可以接受参数(当然),可以调用其他视图助手(包括部分助手)。考虑他们的模板功能。我喜欢将它们用于需要很多的简短任务,例如$this->caseLink($case)
生成格式正确的<a href='/case/2' class='case project'>Project</a>
标记。