php - 如何在 Zend Framework 中创建模块化 MVC 组件

标签 php model-view-controller zend-framework

我在 Zend Framework 应用程序中创建模块化可重用组件时遇到了问题。在这种情况下,我不是指 Zend Framework 模块,而是指具有可重用 MVC 小部件的能力(如果您愿意)。我遇到的问题可能对我的实现来说非常特殊,但如果有人能给我指出正确的方向,我很乐意把它扔掉并重新开始。无论如何,细节和代码有望更好地解释事情,即使我正在做的不是最好的方式它应该显示我正在努力实现的目标:

一个简单的例子是邮件列表注册表单。我想将其包含在使用不同 Controller 的网站的几个页面上,这在如何处理数据和返回相关消息方面提出了一些问题。我不想做以下任何一项,因为它们真的很臭:

  1. 创建一个带有表单处理的基础 Controller 并扩展(不好)
  2. 相关 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/

相关文章:

PHP 到 DOC - CSS 和图像未在文档文件中应用

PHP/MySQL - 散列到 BIGINT 以确保不重复

zend-framework - Zend 框架 : Checking if route exists from code

zend-framework - doctrine2实体关联有什么问题

php - 工厂关系返回 null laravel 测试

php - 覆盖模块的 Yii 登录 URL

javascript - 在线测试系统asp.net mvc

java - MVC结构中图形的问题

java - MVC验证问题