我一直在我的Zend Framework應用程序中創建模塊化可重用組件。在這種情況下,我不是指Zend Framework模塊,而是指能夠擁有可重用的MVC widgety的東西,如果你喜歡的話。我遇到的問題可能對我的實施非常特別,但如果有人能指引我走向正確的方向,我很樂意將其拋出並重新開始。無論如何,具體細節和代碼將有望更好地解釋事情,即使我正在做的不是最好的方式,它應該顯示我想要實現的:如何在Zend框架中創建模塊化MVC組件
一個簡單的例子是郵件列表註冊表單。我想在網站的幾個頁面上使用不同的控制器,這在如何處理數據和返回相關消息方面存在一些問題。我不想請執行下列操作,因爲他們真的聞:
- 創建與表單處理的基本控制器和擴展(壞)相關控制器(更糟糕的是
- 重複的表單處理代碼! )
乾淨的路要走感覺我創建一個新的控制器來處理郵件列表形式的數據,使用一個視圖助手可以輕鬆地輸出表和相關標記到所需的頁面,然後重定向回在表單處理完畢後發生註冊的頁面。然而,我想使用Zend_Form提供的表單驗證,這意味着如果驗證失敗,我需要將表單對象傳回給視圖幫助器,但在相同的請求中。我目前正在通過將它設置爲視圖上的一個變量,然後轉回到上一頁而不是重定向來做到這一點,這是好的(ish)。如果驗證確定,那麼我寧願使用重定向回到原始頁面。我在做這件事時遇到了麻煩,因爲我想將消息傳遞迴組件以瞭解註冊狀態。通常我會使用FlashMessenger Action Helper,在這種情況下我可以命名空間,所以消息不會與其他頁面數據衝突,但我無法從View Helper中訪問它。所以目前我也在這裏轉發。如果用戶刷新頁面並保持URL清潔,我更願意使用重定向來防止表單重新提交。我意識到我基本上希望在頁面內擁有一個迷你MVC調度過程,我認爲這就是操作棧的作用。我真的不知道這些,但任何指針將不勝感激。這是我的當前代碼:
控制器:
<?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(模塊/控制器/動作),這是在視圖助手產生的字符串。我寧願在$ form-> isValid($ _ POST)塊內重定向。
視圖助手:
<?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;
}
}
獲取前端控制器的視圖助手的一個實例是不理想,但我寧願封裝儘可能多地。
如果我有一個表單驗證失敗的對象,我可以將它傳遞迴助手以輸出錯誤消息。如果我有一些消息要呈現,我也可以將它們傳遞給幫手。
在我看來,劇本我使用的幫手,像這樣:
<?=$this->mailingList($this->mailingListForm, $this->mailingListMessages);?>
如果沒有mailingListForm或mailingListMessages對鑑於MailingListController被設置,它會輸出一個新形式的任何消息。
任何幫助,非常感謝!
所以我發現,你可以在一個視圖助手得到一個動作助手的保持。你可以這樣靜態地執行:Zend_Controller_Action_HelperBroker :: getStaticHelper('flashMessenger')。儘管如此,這並不是MVC。我相信肯定有更好的方法? – baseten 2012-01-03 22:33:05
所以我一直在閱讀更多關於動作堆棧和動作助手的信息。兩者都提供瞭解決這個問題的潛在方法,但都會產生大量不必要的開銷,甚至可能在ZF的未來版本中被刪除[link](http://www.rmauger.co.uk/2009/03/why-the -zend-framework-actionstack-is-evil /)我發現這篇文章很有用,它似乎暗示我正在以正確的方式[鏈接](http://robertelwell.info/blog/zend-partial-vs -helper /)我正在考慮編寫一個動作助手來處理我的視圖幫助器中不應該存在的部分。有人有想法嗎? – baseten 2012-01-04 10:25:13