我在 Zend Framework 应用程序中创建模块化可重用组件时遇到了问题。在这种情况下,我不是指 Zend Framework 模块,而是指具有可重用 MVC 小部件的能力(如果您愿意)。我遇到的问题可能对我的实现来说非常特殊,但如果有人能给我指出正确的方向,我很乐意把它扔掉并重新开始。无论如何,细节和代码有望更好地解释事情,即使我正在做的不是最好的方式它应该显示我正在努力实现的目标:
一个简单的例子是邮件列表注册表单。我想将其包含在使用不同 Controller 的网站的几个页面上,这在如何处理数据和返回相关消息方面提出了一些问题。我不想做以下任何一项,因为它们真的很臭:
- 创建一个带有表单处理的基础 Controller 并扩展(不好)
- 相关 Controller 中的重复表单处理代码(更糟!)
我觉得最干净的方法是创建一个新的 Controller 来处理邮件列表表单数据,使用 View 助手轻松地将表单和相关标记输出到所需的页面,然后重定向回发生注册的页面一旦处理完表格。但是,我想使用 Zend_Form 提供的表单验证,这意味着如果验证失败但在同一请求中,我需要以某种方式将表单对象传递回 View 助手。我目前通过将其设置为 View 上的变量然后转发回上一页而不是重定向来执行此操作,这没问题(ish)。如果验证没问题,那么我宁愿使用重定向回到原始页面。我在执行此操作时遇到了麻烦,因为我想将有关注册状态的消息传递回组件。通常我会使用 FlashMessenger Action Helper,在这种情况下我可以为它命名空间,这样消息就不会与其他页面数据冲突,但我无法从 View Helper 中访问它。所以目前我也在转发这种情况。如果用户刷新页面并保持 URL 干净,我更喜欢重定向以防止重新提交表单。我意识到我本质上想在一个页面中有一个迷你 MVC 调度过程,我认为这就是 Action 堆栈的用途?不过,我真的对此了解不多,将不胜感激任何指点。这是我当前的代码:
Controller :
<?php
class MailingListController extends Zend_Controller_Action {
public function insertAction() {
$request = $this->getRequest();
$returnTo = $request->getParam('return_to');
if(!$request->isPost() || (!isset($returnTo) || empty($returnTo))) {
$this->_redirect('/');
}
$mailingList = new Model_MailingList();
$form = new Form_MailingList();
$returnTo = explode('/', $returnTo);
if($form->isValid($_POST)) {
$emailAddress = $form->getValue('email_address');
$mailingList->addEmailAddress($emailAddress);
$this->view->mailingListMessages = $mailingList->getMessages();
$this->view->mailingListForm = "";
}
else {
$this->view->mailingListForm = $form;
}
$this->_forward($returnTo[2], $returnTo[1], $returnTo[0]);
}
}
return_to 是包含当前 URI(模块/ Controller / Action )的字符串,在 View Helper 中生成。我更愿意在 $form->isValid($_POST) block 内重定向。
查看助手:
<?php
class Zend_View_Helper_MailingList extends Zend_View_Helper_Abstract {
public function mailingList($form, $messages = "") {
if(!isset($form)) {
$request = Zend_Controller_Front::getInstance()->getRequest();
$currentPage = $request->getModuleName() . '/' . $request->getControllerName() . '/' . $request->getActionName();
$form = new Form_MailingList();
$form->setAction('/mailing-list/insert');
$form->setCurrentPage($currentPage);
}
$html = '<div class="mailingList"><h2>Join Our Mailing List</h2>' . $form;
$html .= $messages;
$html .= '</div>';
return $html;
}
}
在 View Helper 中获取 Front Controller 的实例并不理想,但我更愿意尽可能地封装。
如果我有一个验证失败的表单对象,我可以将它传递回帮助程序以输出错误消息。如果我有一些消息要呈现,我也可以将它们传递给助手。
在我的 View 脚本中,我使用的是这样的助手:
<?=$this->mailingList($this->mailingListForm, $this->mailingListMessages);?>
如果 MailingListController 在 View 上既没有设置 mailingListForm 也没有设置 mailingListMessages,它将输出一个没有消息的新表单。
非常感谢任何帮助!
最佳答案
使用 ajax 似乎是最佳方式。 View Action Helper 仅用于首次加载邮件表单。
Controller
class MailingListController extends Zend_Controller_Action {
public function insertAction() {
$request = $this->getRequest();
$form = new Form_MailingList();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$mailingList = new Model_MailingList();
$emailAddress = $form->getValue('email_address');
$mailingList->addEmailAddress($emailAddress);
$form = $mailingList->getMessages();
}
}
$this->view->form = $form;
}
}
查看脚本 insert.phtml
<?php echo $this->form; ?>
表单类
class Form_MailingList extends Zend_Form {
public function init() {
//among other things
$this->setAttrib('id', 'mailing-list-form');
$this->setAction('/mailing-list/insert');
}
}
查看助手
class Zend_View_Helper_MailingList extends Zend_View_Helper_Abstract {
public function mailingList() {
$this->view->headScript()->appendFile('/js/mailing-list.js');
return '<div id="mailing-list-wrap">' . $this->view->action('insert', 'mailing-list') . '</div>';
}
}
JS文件 mailing-list.js
$(document).ready(function() {
$('#mailing-list-form').submit(function() {
var formAction = $(this).attr('action');
var formData = $(this).serialize();
$.post(formAction, formData, function(data) {
//response going in form's parent container
$(this).parent().html(data);
});
return false;
});
});
关于php - 如何在 Zend Framework 中创建模块化 MVC 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8712288/