Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mvc] Wybor widoku dla poszczegolnych akcji
Forum PHP.pl > Forum > PHP > Object-oriented programming
Helios
Witam

Moze najpierw przedstawie ogolny schemat dzialania mojego systemu.

- Fasade stanowi FrontController
- FrontController tworzy instancje obiektow ResponseContext, RequestContext
- FrontController korzysta z pomocy ApplicationController
- ApllicationController wybiera z zadania modul i akcje do wykonania
- Mapper akcji parsuje plik XML i zwraca dane dt. lancuchow akcji, widokow dla poszczegolnych rezultatow wykonania danej akcji itd.
- ApllicationController korzysta z mappera akcji i udostepnia konrolerowi informacje o lancuchach akcji i widokach
- FrontController wykonuje w petli lancuchy akcji na danych modulach udostepniajac im kontekst Request i Response, a nastepnie wyswietla widok

I teraz moje pytanie. Chce miec mozliwosc generowania listy newsow w postaci xhtml, rss, pdf itd., a wiec nie chce na sztywno deklarowac, ze np. widok musi byc realizowany przez Smarty. Chce jakos zorganizowac wybor wyjscia w trakcie dzialania aplikacji.
Jak byscie rozwiazali ten problem? Wymyslilem, ze nieglupim rozwiazaniem byloby, aby zajal sie tym mapper akcji. W tym przypadku musialbym deklarowac w pliku XML typ wyjscia np.:

  1. <module name="News">
  2.      <command name="add">
  3.            <state id="1">
  4.                  <forward>getHtmlList</forward>
  5.            </state>
  6.      </command>
  7.      <command name="getHtmlList">
  8.            <view type="html">news.tpl</view>
  9.      </command>
  10.      <command name="getPdfList">
  11.            <view type="pdf">news.pdf</view>
  12.      </command>
  13. </module>


FrontController mialby korzystac z fabryki widokow, tworzyc widok typu zdefiniowanego w akcji (zakladajc ze fabryka widokow zwraca system widokow z zaimplementowanym interface'em View, aby wymusic istnienie metody display)

  1. <?php
  2. $objView = ViewManager::getView($objAppController->getViewType());
  3. $objView->display($objAppController->getView(), $objResponseContext);
  4. ?>


Myslicie, ze jest sens bawic sie w cos takiego, czy lepiej zrobic rozpoznawanie typu widoku na podstawie rozszerzenia pliku wlasnie w fabryce widokow? A moze macie zupelnie inne rozwiazanie?
NoiseMc
Wedlug mnie definiowanie domyslnego rodzaju widoku dla kazdej akcji jest nieglupie aczkolwiek zdefiniowalbym domyslnie dla wszystkich akcji widok html, a dla wyjatkow dodal mape wczytywana tak jak pokazales z XML i pamietalbym o mozliwosci zmiany rodzaju widoku w locie poprzez parametr w url (moze bedziesz chcial zeby akcja zwracala Ci json przy wlaczonym JS albo html przy wylaczonym wtedy w wywolaniach ajaxowych w url moglbys wskazywac ze chcesz dostac json).
Cysiaczek
@Helios - w końcu spotykam osobę, która myśli podobnie do mnie ;p. Mój system działa bardzo podobnie.
Przyjąłem, że typ wyjścia jest określany poprzez parametr w URL.
Np.
http://host.pl/module/action
Domyślnie przyjmie, że ma wygenerować stronę www, z nagłówkami, sekcją meta itp.

Z kolei to samo żądanie, ale...
http://host.pl/module/action/output_xml
Wygeneruje plik XML.

Jeszcze inaczej
http://host.pl/module/action/ajax_yes

Może niezbyt to ładnie wygląda, ale system wie, ze jest to żądanie httpRequest, przy którym nie musi generować calego dokumentu (x)html, a jedynie jego część. Uzyskuję w ten sposób system w którym warstwa widoku działa wg. wzorca 2 Step View, ale: o ile dla zwykłych reqestów widok jest efektem złączenia wielu widoków w jeden, to w przypadku ajaxa - wysylany jest tylko "mały widok" jednej akcji.

  1.      <getComments>
  2.            <status>
  3.                  <ok>
  4.                                <slot>index</slot> <!-- plik z układem złączającym wiele widoków - wywoływany w momencie zwykłego requesta-->
  5.                        <view>show_comments</view> <!-- plik z widokiem właściwym dla tej akcji - wysyłany przy httpRequest  -->
  6.                  </ok>
  7.            </status>
  8.      </getComments>


Wszelkie próby określania z góry (w np. XML) jaki output powinna dać akcja są moim skazane na porażkę, jeśli chcesz jednoczesnie utrzymać maksymalną elesytyczność systemu. Nawet logiczne jest, że to użytkownik powinien określać, w jakiej formie chce otrzymać odpowiedź.

Pozdrawiam.
Helios
Ok, w takim razie zalozmy, ze bede przekazywal typ widoku w linkach np.:

http://example.com/news,read,,1234
http://example.com/news,read,pdf,1234

Jak to teraz rozegrac. Chcialbym zachowac niezaleznosc, moc raz odpalic system przez http a drugi raz pod konsola np. Czy powinienem stworzyc abstrakcyja klase Request i na jej podstawie utworzyc HttpRequest i ConsoleRequest a w nich metody getModule, getAction, getViewType?

  1. <?php
  2. abstract class Request {
  3.  
  4. private $params = array();
  5.  
  6. public function get($key){
  7. // implementacja
  8. }
  9.  
  10. public function set($key, $val){
  11. // implementacja
  12. }
  13.  
  14. abstract public function getModule();
  15. abstract public function getAction();
  16. abstract public function getViewType();
  17.  
  18. }
  19.  
  20. class HttpRequest extends Request {
  21.  
  22. public function getModule(){
  23. return $this->get('module');
  24. }
  25. // itd.
  26. }
  27. ?>


Czy pobieranie typu widoku, poczatkowej akcji i modulu to zadanie dla innej klasy, czy moze byc udostepniane w klasie kontekstu zadania?

Pozdrawiam
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.