Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZF] Znów te "wspólne bloki"
Forum PHP.pl > Forum > PHP > Frameworki
coolin1986
Znów chcę poruszyć temat wspólnych elementów (bloków) w projektach opartych o ZF. Każdy ma swoje podejście i rozwiązanie do tego tematu i zaczynam się w tym gubić... jestem na etapie zapoznawania się z Zendem więc nie chcę wejść na zła drogę... wszystko ma być profesjonalne i zgodne z koncepcją twórców zend framework.

Większość osób na tym forum zaleca stosowanie w layoutach helpera widoku "action" czyli coś takiego:
<div class="box_menu">{$this->action( MenuController ...... )}</div>, co dla mnie jest totalnym nieporozumieniem, moim zdaniem widoki nie mogą wywoływać innych akcji, ponieważ ich funkcją jest tylko sztywne wyświetlanie tego co wygenerował kontroller. Nie wiem może mam złe podejście i myśle trochę po staremu, ale jednak nie lubię bałaganu w aplikacjach. Jak ktoś ma inne zdanie to proszę mnie poprawić i udowodnić dlaczego tak nie jest, będę bardzo wdzięczny smile.gif

Słabo znam Zenda ale spróbowałem znaleźć rozwiązanie i wyszło mi coś takiego:

myproject\application\views\layouts\layout.phtml
  1. <div id="menu">
  2. <?php echo $this->layout()->menu ?>
  3. </div>
  4. <div id="content">
  5. <?php echo $this->layout()->content ?>
  6. </div>


myproject\application\controllers\indexController.php
  1. <?php
  2. function menuAction(){
  3. $mainMenu = array(
  4. array('title'=>'Home', 'url'=>$this->view->baseUrl().'/'),
  5. array('title'=>'Oferta', 'url'=>$this->view->baseUrl().'/oferta/'),
  6. array('title'=>'Articles', 'url'=>$this->view->baseUrl().'/articles/'),
  7. array('title'=>'About', 'url'=>$this->view->baseUrl().'/about/'),
  8. );
  9.  
  10. $this->view->menu = $mainMenu;
  11. $this->_helper->viewRenderer->setResponseSegment('menu');
  12.  }
  13. ?>


myproject\library\home\controller\plugin\ActionSetup.php
  1. <?php
  2. /**
  3.  * Front Controller plug in to set up the action stack.
  4.  *
  5.  */
  6. class Home_Controller_Plugin_ActionSetup extends Zend_Controller_Plugin_Abstract
  7. {
  8. public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
  9. {
  10. $front = Zend_Controller_Front::getInstance();
  11. if (!$front->hasPlugin('Zend_Controller_Plugin_ActionStack')) {
  12. $actionStack = new Zend_Controller_Plugin_ActionStack();
  13. $front->registerPlugin($actionStack, 97);
  14. } else {
  15. $actionStack = $front->getPlugin('Zend_Controller_Plugin_ActionStack');
  16. }
  17.  
  18. $menuAction = clone($request);
  19. $menuAction->setActionName('menu')
  20. ->setControllerName('index');
  21. $actionStack->pushStack($menuAction);
  22.  
  23. }
  24. }
  25. ?>


Menu się wyświetla w kazdym kontrollerze i akcji, a definiuje się go tylko jeden raz.
Tylko teraz taki problem, jeśli wejde do http://myproject/index/menu oczywiście wyświetla mi się menu dwa razy.
I drugie: gdybym chciał w innym kontrollerze zmienić wartości przekazywane do tego menu niestety wyświetlają sie zawsze te z indexController.php. Jak to naprawić, albo obejść?

Bedę wdzięczny za każdą radę, zgodną z koncepcją MVC oczywiście winksmiley.jpg

Przepraszam za możliwe błedy, jestem cudzoziemcem.
Martio
Cytat
Tylko teraz taki problem, jeśli wejde do http://myproject/index/menu oczywiście wyświetla mi się menu dwa razy


Lepiej umieścić bloki (komponenty) w osobnym kontrolerze, np. CommonController, NavController czy ComponentController. Teraz masz tylko menu, a potem może dojść sidebar i inne bloki. W metodzie inicjalizującej kontroler akcji można zastosować mały trick, by kontroler ten nie był dostępny w poziomu URL-a:

  1. <?php
  2. class CommonController extends Zend_Controller_Action
  3. {
  4. /**
  5.  * Initialize object
  6.  */
  7. public function init()
  8. {
  9. // solusion for private controller
  10. if ($this->getRequest()->getParam('controller') == 'common') {
  11. $this->_redirect('/', array('exit' => true));
  12. }
  13. }
  14. }
  15. ?>


Cytat
I drugie: gdybym chciał w innym kontrollerze zmienić wartości przekazywane do tego menu niestety wyświetlają sie zawsze te z indexController.php. Jak to naprawić, albo obejść?


Ustaw sobie łańcuszek akcji w metodzie inicjalizującej dany kontroler zamiast w pluginie. Zawsze możesz przekazać indywidualne parametry dla danego modułu (kontrolera akcji):

  1. <?php
  2. class BlogController extends Zend_Controller_Action
  3. {
  4. /**
  5.  * Initialize object
  6.  */
  7. public function init()
  8. {
  9. if (!$this->getRequest()->isXmlHttpRequest()) {
  10. // create a tasks list for this module
  11. $this->_helper->actionStack('header', 'common');
  12. $this->_helper->actionStack('sidebar', 'common');
  13. $this->_helper->actionStack('footer', 'common');
  14. }
  15. }
  16.  
  17. (...)
  18. }
  19. ?>


Poważną wadą jest ponowne zrenedrowanie ustawionych akcji w przypadku użycia metody narzędziowej $this->_forward(). Można to rozwiązać w mało elegancki sposób jak ten:

  1. <?php
  2. class BlogController extends Zend_Controller_Action
  3. {
  4. /**
  5.  * Initialize object
  6.  */
  7. public function init()
  8. {
  9. if (!$this->getRequest()->isXmlHttpRequest() && $this->getRequest()->getActionName() != 'index') {
  10. $this->_helper->actionStack('header', 'common');
  11. $this->_helper->actionStack('sidebar', 'common');
  12. $this->_helper->actionStack('footer', 'common');
  13. }
  14. }
  15.  
  16. /**
  17.  * Forward to list posts of blog
  18.  */
  19. public function indexAction()
  20. {
  21. $this->_forward('list');
  22. }
  23.  
  24. /**
  25.  * List posts of blog
  26.  */
  27. public function listAction()
  28. {
  29. }
  30. }
  31. ?>


Jeżeli wpadniesz na lepsze rozwiązanie to zademonstruj proszę w tym topicu smile.gif

Można to rozwiązać też za pomocą wzorca "Two Step View". Tutaj mały poradnik. Zerknij na załączony tam Webinar.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.