Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MVC budowa widoku
Forum PHP.pl > Forum > PHP > Object-oriented programming
morawcik89
W jednym za artykułów przeczytałem o takim tworzeniu widoku:
Kod
class WebPage{
     private $pageController;
     private $controllerStyle;
     private $page='';
     public function __construct(PageController $pageController){
         $this->pageController=$pageController;
         $this->controllerStyle=$pageController->getStyle();
     }
     public function doHeader(){
         $this->page='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="stylesheet" href="defaultstyle.css" type="text/css" /><title>Sample Web Page</title></head>';
     }
     public function doBody(){
         $this->page.='<body><div id="header"><h1>Header section</h1></div><div id="navbar"><ul><li><a href="#" title="Link 1">Link 1</a></li><li><a href="#" title="Link 2">Link 2</a></li><li><a href="#" title="Link 3">Link 3</a></li><li><a href="#" title="Link 4">Link 4</a></li><li><a href="#" title="Link 5">Link 5</a></li><li><a href="#" title="Link 6">Link 6</a></li></ul></div><div id="leftcol"><h1>Left column</h1></div><div id="centercol"><h1>Center column</h1></div><div id="rightcol"><h1>Right column</h1></div>';
     }
     public function doFooter(){
         $this->page.='<div id="footer"><h1>Footer section</h1></div></body></html>';
     }
     public function getPage(){
         return $this->page;
     }
     public function getControllerStyle(){
         return $this->controllerStyle;
     }
}


Czy tak powinno się tworzyć klasy widoku czy jest na to może inny lepszy sposób?
.radex
to NIE jest widok, tylko klasa do obsługi layoutu/widoku.
batman
1. popraw bbcode, ponieważ teraz nie da się tego przeczytać. Zamiast code użyj php.
2. Bardzo słaby przykład. Szukaj dalej.
3. IMHO powinno to wyglądać mniej więcej tak. Zapis jest w znacznej mierze koncepcyjny, więc nie bierz go dosłownie.
  1. <?php
  2. class View
  3. {
  4. /**
  5.  * @var array $_data tablica do przechowywania zmiennych, ktore zostana przekaza
    ne do widoku
  6.  */
  7. private $_data = array()
  8.  
  9. /**
  10.  * Pusta metoda do przeciazenia w konkretnym widoku
  11.  */
  12. public function init() {
  13. }
  14.  
  15. /**
  16.  * Dodawanie naglowkow (znaczniki meta)
  17.  */
  18. public function addHeader() {
  19. }
  20.  
  21. /**
  22.  * Dodawanie javascript
  23.  */
  24. public function addScript() {
  25. }
  26.  
  27. /**
  28.  * Dodawanie javascript
  29.  */
  30. public function addStyle() {
  31. }
  32.  
  33. /**
  34.  * Zapisanie wartosci jakiejs zmiennej, ktora pozniej bedzie uzyta w widoku
  35.  */
  36. public function setVar() {
  37. }
  38.  
  39. /**
  40.  * Dodanie tytulu strony
  41.  */
  42. public function setTitle() {
  43. }
  44.  
  45. /**
  46.  * Wygenerowanie widoku
  47.  */
  48. final public render() {
  49. }
  50. }
  51.  
  52. class SomeView extends View
  53. {
  54. public function init() {
  55. // jakies operacje dla tego widoku, np wywolanie $thia->addHeader()
  56. }
  57. }
  58. ?>


A plik widoku, to zwykły html, do którego przekazujesz odpowiednie zmienne.
Trobin
Najlepiej zajrzeć jak to działa w przykładowym frameworku winksmiley.jpg . To bardzo pomaga w zrozumieniu tych mechanizmów (nie mówię, że od razu zaczniesz stukać pięknie kod, ale załapiesz podstawy smile.gif ). Aha, polecam Kohana winksmiley.jpg .
morawcik89
Czyli sam widok ma wyglądać jak plik html z małymi (choć licznymi w tym przypadku) kawałkami kodu php który już ma przypisaną wartość?
LBO
Cytat(batman @ 15.07.2008, 19:52:24 ) *
ciach


@batmanie, spierałbym się - sama klasa widoku nie powinna udostępniać takich metod - powinna się skupić raczej na wybieraniu szablonów, przyjmowaniu zmiennych etc. działań istotnych dla Widoku jako takiego.
Natomiast klasy dziedziczące to inna sprawa, one mogą być już wyspecjalizowane.
Czyli:
  1. <?php
  2. class View
  3. {
  4. // funckjepotrzebne do działania widoku
  5. }
  6. class HtmlView extends View
  7. {
  8. // tutaj funkcje z dodawaniem znaczników stylów, skryptów, a nawet jakieś helpery
  9. }
  10. ?>


Oczywiście to w kontekście bardzo prostej implementacji MVC.
batman
Cytat
@batmanie, spierałbym się (...) Oczywiście to w kontekście bardzo prostej implementacji MVC.
MVC można interpretować na wiele sposobów i każdy z nich będzie dobry (oczywiście w granicach rozsądku). Podejść do jednego problemu może być wiele. Poza tym kod, który podałem, nie jest wyznacznikiem jak klasa widoku powinna wyglądać, a jedynie luźną propozycją. Mimo to, pozostawiłbym w tej klasie takie metody jak dodawanie skryptów, czy stylów.
cbagov
Sposob w Smarty jest absolutnie wystarczajacy i wygodny, takze polecam sie wzorowac na nim, jesli juz.

A o przykladzie jaki znalazles z kodem:

doBody(){
$this->page.='<body><div ....

po prostu ZAPOMNIJ.

Tak samo kod powyzej z
function setTitle() ,
addScript()

itd,
no chyba nie bede do kazdego nowego elementu na stronie robil sobie funkcji hehe, takze przyjmuje to jako zart.
Sedziwoj
Cytat(batman @ 15.07.2008, 23:09:29 ) *
Mimo to, pozostawiłbym w tej klasie takie metody jak dodawanie skryptów, czy stylów.


A wyjaśnij mi po co mi, w CSV, XML czy podobnych, skrypt lub style?
Chyba zbyt się uzależniłeś, że widok, to html.
Do tego nie wiem czy u mnie bym przekonał grafika aby zaglądał do kodu PHP, aby zmienić sobie style... (chyba że inaczej byś to rozwiązał niż wydaje się mi że jest)

EDIT dodałem dwa przecinki dla poprawienia czytelności.
morawcik89
Nie chcę być nieuprzejmy ale po waszej rozmowie już nic nie rozumiem.
Moli
@Sedziwoj - Dodawanie tych metod w klasie nie jest dobrym pomysłem. W końcu po to oddziela się widok od modelu czy kontrolera. Ale danie w widoku np.:
Kod
<?php $html->js('nazwa'); ?>

czy np. na systemie szablonów
Kod
{html js='nazwa'}


Nie jest utrudnieniem nawet dla grafika, a ułatwia pracę smile.gif Nie trzeba podawać ścieżki do pliku itp.

Ja u siebie w widoku mam do obsługi html tylko 3 funkcje - doctype,base,style,js. Te które używa się w każdym projekcie a nie chce się za każdym razem pisać tego samego.
LBO
@moli, ale tu nie o to chodzi w dyskusji. Rzecz w tym, żeby nie tworzyć podstawowego Widoku zorientowanego na HTML.
Ja nie mam nic przeciwko, tylko, żeby była możliwość posiadać widoki innych typów (Json, XML etc).
Sedziwoj
Cytat(Moli @ 16.07.2008, 11:37:47 ) *
Nie jest utrudnieniem nawet dla grafika, a ułatwia pracę smile.gif Nie trzeba podawać ścieżki do pliku itp.


Dokładnie, to co należy do konkretnej specyfikacji wypada do niej, można stosować władowanie js/css w PHP ale to też muszą być szablony (w sensie pliki zewnętrzne), aby grafik bez problemu mógł je sobie zmieniać, a nie mnie ciągle męczyć. To właśnie doskonale widać co jest dobrym rozwiązaniem, a co nie, kiedy widok, prezentację danych tworzy inna osoba, która nie wsadza nosa w to co my robimy. Bo o to chodzi w tej idei, rozdzielenie warstw, aby ułatwić.
batman
Cytat
A wyjaśnij mi po co mi, w CSV, XML czy podobnych, skrypt lub style?

Zawsze można nieco zmodyfikować mój przykład
  1. <?php
  2. class View
  3. {
  4. final public function render() {}
  5. }
  6.  
  7. class HtmlView extends View
  8. {
  9. // metody dodajace css, js, itd
  10. }
  11.  
  12. class SomePageView extends HtmlView
  13. {
  14. // konkretne uzycie metod rodzica
  15. }
  16. ?>

Analogicznie można utworzyć klasy XmlView, czy CsvView, które będą posiadały odpowiednie metody.

Cytat
Nie jest utrudnieniem nawet dla grafika, a ułatwia pracę

Dokładnie o to mi chodziło. Metody przyjmowałyby jedynie nazwy plików, a nie ich zawartość. Wówczas edycja styli nie sprawi problemów grafikowi.


Cytat
Nie chcę być nieuprzejmy ale po waszej rozmowie już nic nie rozumiem.

Trochę się zapędziliśmy w dyskusji winksmiley.jpg Ogólnie chodzi o to, by klasa widoku nie zawierała kodu html. Jest to najgorsze z możliwych rozwiązań. Klasa taka powinna umożliwiać dodawanie zmiennych do widoku, które zostaną w nim wyświetlone lub dołączanie stylów, czy js.
A sam plik widoku to, w najprostszej wersji, najzwyklejszy plik html z instrukcjami echo $jakas_zmienna.
Cysiaczek
Warstwa prezentacji dzieli się moim zdaniem na dwa etapy:
1. Logika prezentacji
2. Treść widoku

Pierwszy to właśnie jakaś klasa View, z której wyprowadza się pochodne HtmlView, XmlView itd. Dostarcza metody takiej jak np, setTitle(), setMetaTag()
My jednak nie koniecznie używamy ich sami O ile to możliwe, powinien sie tym zająć jakiś ViewManager, który po konsultacji z wpisami w konfiguracji, wypełni je automatycznie. Oczywiście powinniśmy mieć możliwość zmiany tych ustawień w dowolnym momencie (przed samym procesem generowania rzecz jasna). Tu kwestia istotna - systemy takie jak np. Smarty, czy OPT nie należą do logiki prezentacji - one obsługują treść widoku, a więc sam szablon, do którego podstawia się dane.

Treść widoku, to jak przed chwila wspomniałem - szablon, najlepiej pasywny, czyli taki, który nie komunikuje się z resztą systemu (ale lepiej mieć możliwość - na wszelki wypadek), a jedynie wyświetla przekazane mu przez logikę prezentacji dane. Czy to będą obiekty, ich kolekcje, czy typy proste - nie ma znaczenia.

Gdzie tu miejsce na Smarty? To proste - HtmlView wybiera typ renderingu strony, albo zostaje mu narzucony przez konfigurację (za pośrednictwem ViewManagera)

O, jeszcze obrazek - tylko sie nie czepiajcie szczegółów, bo robiłem na szybko smile.gif

Pozdrawiam.



Aha, żeby nie było - wiem, że tekst i obrazek nie pokrywają się, ale siła i kierunek powiązań między klasami bywają różne. Ważni są uczestnicy procesu.
wlamywacz
Dołączę się do tematu gdyż sam napotkałem na tym etapie pewien problem odnośnie widoku moja classa view:
  1. <?php
  2. class view {
  3.  
  4. private $content;
  5.  
  6. public function __construct() {
  7.  
  8. $this->template = 'standard';
  9.  
  10. }
  11.  
  12. public function setTemplate($template) {
  13.  
  14. $this->template = $template;
  15.  
  16. }
  17.  
  18. public function setContent($content) {
  19.  
  20. $this->content = $content;
  21.  
  22. }
  23.  
  24. public function show() {
  25.  
  26. $content = new Smarty();
  27. $content->templae_dir = FOLDER;
  28. $content->compile_dir = FOLDER . 'compile/';
  29. $content->cache_dir = FOLDER . 'cache/';
  30. $content->caching = 0;
  31. $content->error_reporting = E_ALL; 
  32. $content->assign( 'content' , $this->content);
  33. $content->assign( 'template' , $this->template);
  34. $content->display($this->template.'/template.tpl');
  35.  
  36. }
  37.  
  38. public function newsStartPage($array, $pager, $logined) {
  39.  
  40. $content = new Smarty();
  41. $content->template_dir = FOLDER;
  42. $content->compile_dir = FOLDER . 'compile/';
  43. $content->cache_dir = FOLDER . 'cache/cache_inne/';
  44. $content->caching = 0;
  45. $content->error_reporting = E_ALL; 
  46. $content->assign( 'news' , $array);
  47. $content->assign( 'pager' , $pager);
  48. return $content->fetch($this->template.'/news.tpl');
  49.  
  50. }
  51.  
  52. public function news($array, $msg, $comments, $logined) {
  53.  
  54. $content = new Smarty();
  55. $content->template_dir = FOLDER;
  56. $content->compile_dir = FOLDER . 'compile/';
  57. $content->cache_dir = FOLDER . 'cache/cache_inne/';
  58. $content->caching = 0;
  59. $content->error_reporting = E_ALL; 
  60. $content->assign( 'new' , $array);
  61. $content->assign( 'msg' , $msg);
  62. $content->assign( 'comments' , $comments);
  63. return $content->fetch($this->template.'/new.tpl');
  64.  
  65. }
  66. }
  67. ?>


Chodzi dokładnie o funkcję show() przekazuje do niej przez setContent() treść którą ma wyświetlić z innych klas (news itp.). Jednak w template.tpl będzie jeszcze menu którego struktura jest zależna od danych w bazie, jak przekazać to do show() te dane? Chyba rozumiecie w czym problem?
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.