Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Widok MVP, Renderowanie roznych typow widoku
marcio
post
Post #1





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


Hej doszedlem do wniosku ze w moim fw widok, ogolnie warstwa prezentacji jako szablon to za malo, w sensie gdy zajdzie potrzeba na wyswietlenie innego fotmatu pdf,xml,text,csv czy json bedzie lipa i albo nie da rady albo bede musial kombinowac w kontrolerze i robic rzeczy ktorych nie powinno sie robic.

Wiec postanowilem poszerzyc fw o nowa funkcjonalnosc, oprocz widokow jako szablony mozna uzywac klasy.

Jednak nie wiem zabardzo jak to najlepiej rozwiazac do tej pory doszedlem do 2 sposobow:
-Osobna klasa widoku na kazdy format czyli News_View_Html,News_View_Xml itp...itd...
-Jedna ogolna klasa News_View implementujaca interfejs IView ktory ma metody: renderHtml,renderXml,renderJson itp..itd

Moze pokaze pseudo kod to bedzie bardziej wiadomo o co mi chodzi:
  1. interface IView {
  2.  
  3. public function render();
  4.  
  5. }
  6.  
  7. //lub
  8.  
  9. interface IView {
  10.  
  11. public function renderHtml();
  12. public function renderText();
  13. public function renderXml();
  14. public function renderJson();
  15. public function renderPdf();
  16.  
  17. }
  18.  

I potem reszta:
  1. <?php
  2.  
  3. class News_View_Html extends Html_View implements IView {
  4.  
  5. public function render() {
  6.  
  7. return $this -> Layout('news', 'components', 'admin');
  8.  
  9. }
  10.  
  11. }
  12.  
  13. class News_View_Xml extends Xml_View implements IView {
  14.  
  15. public function render() {
  16.  
  17. //implemenctacja dla xml'a
  18.  
  19. }
  20.  
  21. }
  22.  
  23. //lub jedna klasa z metodami dla kazdego typu widoku dziedziczaca po bazowej klasie view + interfejs
  24.  
  25. class News_View extends View implements IView {
  26.  
  27. //implementacja assign'ow
  28. public function setVars($vars) {
  29.  
  30. $this -> view -> AddVars($vars);
  31.  
  32. }
  33.  
  34.  
  35. public function renderHtml() {
  36.  
  37. $this -> view -> Layout('news', 'components', 'admin');
  38.  
  39. }
  40.  
  41.  
  42. public function renderXml() {
  43.  
  44. //implementacja dla xml'a
  45.  
  46. }
  47.  
  48.  
  49. //potem implementacja dla text,pdf i json jesli jest potrzeba jak nie to puste metody
  50.  
  51. }
  52.  
  53.  
  54. //klasa kontrolera
  55.  
  56. class News extends Controller implements IController {
  57.  
  58. public function Index() {
  59.  
  60. //pobieranie news'ow z modelu
  61. //ustawiane widoku dla url index.php/Home,Index,Index,html
  62.  
  63. $args = $this -> routing -> getParams();
  64.  
  65. switch($args) {
  66.  
  67. case 'html':
  68. //teraz tak albo osobna klasa dla kazdego widoku albo jedna klasa ze wszystkimi metodami
  69. $view = $this -> News_View_Html;
  70. $view -> AddVars($news);
  71. return $view -> render();
  72.  
  73. //lub
  74.  
  75. $view = this -> News_View;
  76. $view -> setVars($news);
  77. return $view -> renderHtml();
  78.  
  79. break;
  80.  
  81. case 'xml':
  82. //tutaj to samo tylko ze w formacie xml
  83. break;
  84.  
  85. }
  86.  
  87. }
  88.  
  89. }
  90. ?>

Kod pisany na szybko z palca wiec moze sa jakies bledy, to ma byc tylko taki ogolny zarys.

Chodzi o to ktore rozwiazanie jest lepsze, a moze zadne z nich i proponujecie inne...?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
dariuszp
post
Post #2





Grupa: Zarejestrowani
Postów: 30
Pomógł: 0
Dołączył: 9.09.2010

Ostrzeżenie: (0%)
-----


Akurat to co tworze ma charakter komercyjny i nie mogę się podzielić.

Idea jest prosta. W module ma być zaszyta informacja a jakiej postaci potrafi on zwrócić dane. Jeżeli to HTML to powinien on mieć dostarczony szablon do uzupełnienia a później zwrócić kod wynikowy. Jeżeli to JSON, powinien on zebrać dane do tablicy, zakodować do formatu i wyświetlić itp.
Sam dla przykładu by nie tworzyć 10 różnych metod (i trzymać interfejs w jak najprostszej postaci) mam metody które reprezentują jakieś akcje w systemie ale... mogą zwrócić zupełnie inne dane.
Dla modułu jest ustawiany tym zwracanych danych a dalej program działa jak by nigdy nic.

Teraz pytanie - dlaczego warstwa usług ? Oto kilka przypadków które mi ona rozwiązała:

1. (ServiceHTML) Ładując stronę, mam na niej kilka modułów do wyświetlenia. Usługa musi załadować je wszystkie, ustawić ich konfigurację i wykonać. Następnie uzupełnia szablon o ich kod wynikowy.
2. (ServicePOPUP) W momencie gdy np chcę wyświetlić 1 moduł w oknie pop-up, w lightbox lub w jakikolwiek inny sposób, taki moduł powinien mieć załadowany podstawowy szablon HTML (head + body itp) by działać poprawnie. Dodatkowo powinien być załadowany jeden moduł.
3. (ServiceAJAX) Potrzeba mi podmienić na stronie fragment kodu z modułu, muszę dostać surowy kod do podmiany bez dodatków. Czasami chodzi tylko o fragment tekstu albo informację przykładowo o nowych wiadomościach.
4. (ServiceDOWNLOAD) Dane wynikowe muszę dać użytkownikowi do ściągnięcia, trzeba mu przesłać plik, odpowiednie nagłówki itp. Dodatkowo czasami trzeba mu zablokować możliwość ściągania danego pliku.
5. (ServiceSOCKET) Muszę po prostu otworzyć połączenie poprzez socket z jakimś urządzeniem i przesłać dane wg jakiegoś protokołu.
6. (ServiceWAP) Muszę wyświetlić stronę dla urządzeń mobilnych gdzie potrzebny osobny szablon, obrazki niskiej rozdzielczości itp.
7. (ServiceJSON) Gdy dane muszą być zwrócone w formacie JSON.
8. (ServiceXML) Te same dane co poprzednio ale w formacie XML.

I tak się o nic nie martwię. Użytkownik klikając w link wybiera usługę, moduł i akcję jaką chce wykonać. Jeżeli moduł obsługuję daną usługę, ustawiam tym danych wynikowych dla modułu ( $module->setOutputType($service->getOutputType()); $service->run($module); ) to wywoływana jest akcja i dalej wszystko dzieje się w zależności jaka to była usługa. Jeżeli coś jest nie tak (nie ma akcji, nie ma modułu, moduł nie obsługuje danej usługi) to loguję taką informację że coś mogło pójść nie tak i wyświetlam stronę 404.

Jedyne co Ci potrzebne to mała standaryzacja. U mnie dla przykładu usługa HTTP i WAP działają podobnie. Różnica polega na tym że kod modułów jest ładowany w oddzielne szablony gdzie moduły w obu przypadkach zwracają to samo (nie licząc obrazków, jeżeli to możliwe to ładowane są te w niższej rozdzielczości). JSON i XML podobnie. Moduł zwraca tablicę asocjacyjną która jest konwertowana na jeden z formatów przez usługę. Download jest specyficzny. Można nim ograniczać lub zezwalać na ściąganie plików (rozszerzyłem serwer o znakomity moduł xsendfile). Ostatnio kolega podrzucił mi ciekawy pomysł który może przetestuję. Zastanawiam się czy by przypadkiem nie spróbować przepuścić przez PHP plików graficznych. Usługa została by poszerzona i np w wypadku gdy dane zdjęcie było ładowane z zewnętrznego serwera - zabraniał bym to robić bądź też dokładał do niego znak wodny. Taka opcja do włączenia.
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.10.2025 - 16:51