Presenter – rozbor, názorná ukázka chyb
- Ofi
- Člen | 13
Ahoj, byl by tu někdo ochotný mi rozebrat kousek mého presenteru? co se
týče Nette a MVP je to úplně první co pomocí toho dělám, a tak mě
napadlo že názorná ukázka co jsem udělal špatně by mohla pomoct :-)
zveřejňuji jen ovládání jedné šablony – aby to nebylo pracné se
prodírat kodem. děkuju…
<?php
final class ContentPresenter extends Presenter {
public function actionDefault($menuItem = "uvod") {
$this->template->description =
$this->model->getDescription($menuItem);
if($menuItem == "fotogalerie") {
$categoriesBuffer = $this->model->getCategories(0);
$this->template->headerOfCategories = "Fotogalerie";
} else {
$categoriesBuffer = $this->model->getCategories();
$this->template->headerOfCategories = "Nabídka služeb";
}
$this->template->categories = $categoriesBuffer;
$this->template->numInColumns =
$this->getNumOfRecordsInColumns(count($categoriesBuffer));
}
public function renderDefault() {
}
/**
* Tato funkce mi podle počtu záznamů řekne, kolik záznamů náleži do
* kterého ze tří sloupců... Aby bylo jasno, vždy se nejprve vykresluje
* sloupec 1, pak 2, a pak 3... Takže mám-li např 5 vrácených záznamů,
* pomocí tohoto pole předám šabloně informaci, že první a druhý sloupec
* se má vykreslit se dvěmi záznamy a 3.sloupec s jedním...
**/
private function getNumOfRecordsInColumns($countOfRecords) {
$num = $countOfRecords/3;
$numOfCategoriesInColumns[0] = (integer)$num;
$numOfCategoriesInColumns[1] = (integer)$num;
$numOfCategoriesInColumns[2] = (integer)$num;
$border = (integer)($countOfRecords-(3*((integer)$num)));
for($i=0; $i<$border; $i++) {
$numOfCategoriesInColumns[$i]++;
}
return $numOfCategoriesInColumns;
}
}
?>
edit: jen úprava aby se kód nemusel rolovat do strany…
Editoval Ofi (4. 9. 2010 21:40)
- westrem
- Člen | 398
No na vysvetlenie co robit kde a ako pouzivat Render a Action doporucujem poriadne precitat nasledovne
K tvojmu kodu, naozaj by dane veci kludne mohli ist do Render metody. Celkovo by to slo trochu aj zjednodusit, ale kazdy mame svoj coding style a nechcem rypat do toho tvojho len preto, ze ja by som to napisal trosilinku odlisne.
Nechapem tak trochu tej metode getNumOfRecordsInColumns
–
teda chapem co robim, ale nedalo by sa vyuzit toto: Grid
renderind ? Resp. pride mi, ze to co robis tou metodou je uz naozaj starost
view, presenter by nemal apriori vediet, ze chces v sablone nieco delit do
3 stlpcov a pomahat jej s tym, on jej ma len predat data a ona si ich sama
spracuje. Kebyze casom prides na to, ze potrebujes 4 stlpce, musis hned
prepisovat aj presenter, pricom za pouzitia Grid renderingu len jedno cislo
v template.
- Ofi
- Člen | 13
Nechapem tak trochu tej metode getNumOfRecordsInColumns – teda chapem co robim, ale nedalo by sa vyuzit toto: Grid renderind ?
no, jak jsem říkal, s nette začínám.. o tomto jsem nevěděl –
super tip! díky
aj máš pravdu, mělo by to být ve view, já to bral tak, že to je jako
příprava dat než je předá view…
díky za názor, byl přínosný :)
Editoval Ofi (5. 9. 2010 19:00)
- Ani
- Člen | 226
Osobně si myslím, že:
- úvod, fotogalerie a nabídka služeb by měli mít každá svůj view.
- to co dělá metoda getNumOfRecordsInColumns by se asi mělo dělat v šabloně, případně rovnou v modelu.
- rozlišovat jaké kategorie menu ti vrátí getCategories z modelu, takhle natvrdo podle parametru 0 nebo nic, no nevim. Takhle napohled mi to přijde dost neintuitivní, ale když se v tom vyznáš.
Body 2 a 3 nejsou až tak důležité, ale bod jedna by mol znamenat nepochopení základních principů, tak se nad tím zkus zamyslet ;)
Podle toho kousku se to těžko posuzuje.
- westrem
- Člen | 398
Ofi napsal:
No priprava dat, model sa vecsinou pouziva cisto na ziskavanie RAW dat s tym, ze nejak kanonizuje ich typ a sablona s nimi potom robi co uzna za vhodne, preto existuju helpery a filtre.
Priklad: Z modelu si vytiahnes nejaky datum s casom. V jednej sablone ho budes chciet zobrazit iba ako DD.MM.YYYY kdezto napr. v nejakom admin rozhrani bude pre teba dolezite aj presna minuta a hodina kedy sa akcia udiala tak si to vypises ako DD.MM.YYYY HH:MM:SS. V oboch pripadoch z modelu do sablony predas RAW datum (napr. ako int timestamp alebo DateTime object) a az v sablone si s tym robis upravu na pozadovany format.
Ani napsal:
Wow, nejak som si neuvedomil tu logiku za tym, ale mas pravdu, ak to robi to na co sa to javi, tak fotogalerie, uvod a aj nabidka sluzieb by mali byt separatne views, tzn kazdy z nich by mal mat vlastnu render metodu a vlastnu sablonu :)
- Ofi
- Člen | 13
Ani napsal(a):
Osobně si myslím, že:
- úvod, fotogalerie a nabídka služeb by měli mít každá svůj view.
a není to zbytečné, protože ve všech třech případech je kód šablony stejný, jsou pouze jiná data, která view dostane… proto to mám dohromady a ovládá to ContentPresenter…
- to co dělá metoda getNumOfRecordsInColumns by se asi mělo dělat v šabloně, případně rovnou v modelu.
ano ano, souhlasím, jak naznačil kolega nahoře, zbytečně jsem si to zkomplikoval :)
- rozlišovat jaké kategorie menu ti vrátí getCategories z modelu, takhle natvrdo podle parametru 0 nebo nic, no nevim. Takhle napohled mi to přijde dost neintuitivní, ale když se v tom vyznáš.
0 = false, 1= true a 1 je implicitně… vzhledem k tomu že ta metoda má
jen jeden parametr a že jsem k ní napsal dokumentaci a používám IDE mi to
přijde postačující a myslím, že bych to pochopil i za rok :-) možná by
bylo lepší tam psát true a false a nenechávat prázdné kvůli rozlišení,
na to možná dojde ale až při refaktoringu :-)
>
díky za zhodnocení ;-) co ta 1) i tak by to mělo být oddělené? nevznikne
mi tím hodně duplicitního kódu?
Editoval Ofi (6. 9. 2010 16:55)
- Ofi
- Člen | 13
je to v podstatě tak že se pošle šabloně description pro daný menu item a buď všechny položky „nabídka služeb“ (pro úvod a nabídka služeb), nebo fotogalerie (pro fotogalerie) každá stránka pak vypíše nadpis, popis, a stejný formát pro výběr v nabídce služeb nebo fotogalerii… dyžtak postnu i kód šablony :)
{block title}
<title>{$description->menuItem}</title>
{/block}
{block content}
{if isset($description) && $description != null}
<h3>
{$description->menuItem}
</h3>
<p>{!$description->description}</p>
{/if}
{if isset($categories)}
<hr class="multi-separator">
<h3>
{$headerOfCategories}
</h3>
<ul>
{foreach $categories as $key => $value}
{if $key==0 ||
$key==$numInColumns[0] ||
$key==$numInColumns[0]+$numInColumns[1]
}
<li>
{else}
<hr class="separator">
{/if}
<strong>
<a href="{link detail,
String::webalize($headerOfCategories),
$value->seoUrl}">
{$value->title}
</a>
</strong>
<img
src="images/uploaded/{$value->seoUrl}/{$value->firstImage}"
alt="alt"
width="170">
{/foreach}
</ul><hr class="clear">
{/if}
{/block}