Przekazywanie danych z kontrolera MVC do podglądu w PHP
Mam własny, ręcznie rozwijany framework PHP MVC dla niektórych projektów, nad którymi pracuję. Kiedy po raz pierwszy stworzyłem framework, było to w kontekście budowania admin CMS. Dlatego też istniała bardzo miła relacja jeden do jednego między modelem, widokiem i kontrolerem. Masz jeden wiersz w DB, który mapuje do jednego modelu. Kontroler ładuje model i przekazuje go do widoku, który ma być renderowany(np. do formularza edycji). Ładnie, czysto i łatwo.
Jednak teraz, gdy pracuję z przodu strony wszystko się klei. Strona nie zawsze jest widokiem pojedynczego modelu. Może to być Lista katalogów użytkowników z 20 użytkownikami (każdy model użytkownika). Ponadto mogą istnieć metadane dotyczące żądania, takie jak paginacja (bieżąca strona, całkowita liczba stron, liczba wyników) i/lub zapytanie wyszukiwania.
Moje pytanie brzmi, jaki jest najczystszy sposób, aby przekazać wszystkie te dane do widoku?
Niektóre opcje rozważam:
-
Mieć kontroler Utwórz tablicę i przekaż ją do widoku jako pojedynczy parametr:
class UserController{ public function renderView(){ // assume there's some logic to create models, get pagination, etc. $data = array() $data['models'] = $models; $data['currentPage'] = $current; $data['totalPages'] = $total; return $view->render($data); } } class UserView{ public function render($data){ // render the data } }
-
Utwórz właściwości w klasie view i niech kontroler je wypełni:
class UserView{ public $models; public $currentPage; public $totalPages; } class UserController{ public function renderView(){ // assume there's some logic to create models, get pagination, etc. $view = new UserView(); $view->models = $models; $view->currentPage = $current; $view->totalPages = $total; return $view->render(); } }
-
Daj widok jakiś rodzaj ogólnego obiektu HashMap lub kolekcji jako kontener, który może pomieścić dowolną liczbę i nazwę danych.
class UserView{ public $collection = new Collection(); // works like a Java collection } class UserController{ public function renderView(){ // assume there's some logic to create models, get pagination, etc. $view = new UserView(); $view->collection->add($models,'models'); $view->collection->add($currentPage,'currentPage'); return $view->render(); } }
Wiem, że technicznie każdy z może działać, ale nie jestem pewien najlepszego wyboru, lub jeśli brakuje mi lepszego lub bardziej konwencjonalnego wyboru.
3 answers
Polecę koncepcję Fat Models, Chudy Controllers (lub Fat Models Thin Controllers jeśli wolisz...)
Innymi słowy, twój model jest zbyt surowy - Wiązanie Twojego modelu, aby reprezentować tylko coś takiego jak RowDataGateway jest niezwykle ograniczające.
W zasadzie myślę, że dobre modele ukrywają fakt, że w ogóle czytasz dane z bazy danych. Ponieważ w rzeczywistości, Twoje dane mogą być w plikach tekstowych, lub z usługi internetowej, lub cokolwiek innego. Jeśli traktuj swój Model jak tylko gloryfikowany DBAL, skazujesz się na posiadanie ściśle powiązanego kodu w kontrolerach, który po prostu nie pozwoli Ci oderwać się od sposobu myślenia "dane pochodzą tylko z bazy danych".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 05:43:23
Widziałem dwie pierwsze metody zaimplementowane w popularnych frameworkach MVC / templating.
Django używa pierwszej metody, przekazując do widoku słownik zmiennych, których widok używa do wypełnienia szablonu.
Smarty używa drugiej metody, tworząc obiekt Smarty i przypisując wartości do każdej właściwości w kontenerze.
Twoja trzecia metoda wydaje się być zasadniczo taka sama jak druga, z małą architekturą różnice.
Naprawdę, chyba nie powiedziałem nic, o czym nie pomyślałeś. Zasadniczo są to wszystkie pomysły na dźwięki, więc wdrażaj to, co czujesz, że czujesz się najbardziej komfortowo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 05:38:47
W tym, którego używam, automatycznie posiada właściwość view w kontrolerze, która umożliwia dostęp do metod i właściwości w widoku. Wszystkie właściwości publiczne są wtedy dostępne w widoku widoku '$ this' , ponieważ widok jest renderowany w kontekście własnych obiektów.
W kontrolerze:
$this->view->myVar = 'test';
I w widoku:
$this->myVar; // 'test'
To samo dotyczy układu, ponieważ oba są oddzielnymi instancjami tego samego obiektu widoku:
$this->layout->myVar = 'test';
A potem w układ:
$this->myVar; // 'test'
Framework był kiedyś zastrzeżony, ale wkrótce zostanie udostępniony opinii publicznej. Z chęcią wyślę Ci kod, jeśli uważasz, że to pomoże. Pamiętaj, najprostsza odpowiedź jest zwykle najlepszą odpowiedzią.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 06:53:07