Připojení stejné části webu
- grogy
- Člen | 147
Opět zdravím a opět mi jde o best practice, bohužel tu sem nic nenašel (ale ani neprošel celé fórum, je trošku větších rozměrů..) :)
Problém: Web s 10 stránkami, kde na každé je dole stejný malý formulář. Chci ho generovat pomocí NForm (aby to bylo rovnou chráněné pomocí JS i na serveru). A nejde jen o formulář, ale i když to bude menu (generované například z databáze).
Jak to udělat, kam psát logiku a jak to napojit na šablonu. (Řešení pomocí staticky napsat form.phtml a ten includovat do @layout.phtml se mi nezamlouvá).
- na1k
- Člen | 288
Já na takové věci používám vykreslitelné komponenty (vlastní třída
rozšiřující Control
). V presenteru si vytvořím instanci,
případně něco nastavím a předám šabloně. V té pak volám jen
{$mojeKomponenta->render()}
.
Jak to bude řešené v samotné třídě komponenty je zcela na tobě, není
problém si v ní vytvořit Nette formulář, zpracovávat jej, a to třeba
i AJAXově.
Nevím jestli je to best practice, ale funguje to celkem dobře … sám se
ale s Nette pořád učím, takže si určitě počkej na odpověď Nette Gurus
:) Jinak je teď nějakou dobu možné mít v presenteru továrničku na
komponenty a v šabloně volat pouze {control mojeKomponenta}
- grogy
- Člen | 147
Ok, takže jak píše Jod, našel jsem to v dokumentaci (https://doc.nette.org/…n/presenters#…) a myslím že to je velice dobré řešení.
(Když je potřeba půjde vytvořit uvnitř třídy createComponentX() instanci jiné třídy, kde se třeba bude řešit složitější aplikace a tu se jen zavolá její řešení a pomocí widget se vypíše).
Ovšem s implementací to tu mám horší. Vrací mi to (v té části šablony – „Server Error“) ale to myslím, že bude jen mojí chybou.
- grogy
- Člen | 147
Takže jsem to pořešil, ale došel k problému:
<?php
protected function createComponentEditForm()
{
$form = new Form;
$form->addTextArea("text", "Text");
// $form = "Ahoj"; // - po odkomentovani nefunguje, -> Server Error ve vykreslení
return $form;
}
?>
Co tedy použít, kdybych dejme tomu potřeboval vrátit a vypsat jen text (v praxi spíš pole s menu)?
- Ondřej Mirtes
- Člen | 1536
grogy napsal(a):
Takže jsem to pořešil, ale došel k problému:
<?php protected function createComponentEditForm() { $form = new Form; $form->addTextArea("text", "Text"); // $form = "Ahoj"; // - po odkomentovani nefunguje, -> Server Error ve vykreslení return $form; } ?>
Co tedy použít, kdybych dejme tomu potřeboval vrátit a vypsat jen text (v praxi spíš pole s menu)?
Jasně, že to nefunguje, když změniš něco, co má dědit od Component,
na jednoduchý string :) Navíc by ta továrnička měla vypadat, pokud se
nemýlím, takto (pro použití v presenteru je určen AppForm
a
v jeho konstruktoru či pomocí metody presenteru addComponent
ho
s ním musíš svázat):
protected function createComponentEditForm()
{
$form = new AppForm($this, 'EditForm');
$form->addTextArea("text", "Text");
/* alternativně:
$form = new AppForm();
$form->addTextArea("text", "Text");
$this->addComponent($form, 'EditForm');
*/
}
Pokud chceš vypsat něco jiného, než ten formulář, tak si musíš na to vytvořit komponentu či to nějak „hardcodnout“ do toho layoutu. Nemůžeš chtít po jedné továrničce, aby ti vracela vše :) Navíc, jakou logikou bys v ní zjišťoval, jestli chceš vrátit zrovna formulář nebo cokoli jiného?
- kravčo
- Člen | 721
grogy napsal(a):
Co tedy použít, kdybych dejme tomu potřeboval vrátit a vypsat jen text (v praxi spíš pole s menu)?
Obyčajný string do stromu komponentov pridať nejde, akýkoľvek prvok
v ňom musí implementovať rozhranie IComponent
. Jednoduchý
príklad, ako spraviť komponent reprezentujúci string pomocou Controlu by
mohol vyzerať takto:
class StringControl extends Control
{
private $value;
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function render()
{
echo $this->value;
}
}
Podobným spôsobom sa dajú do stromu komponentov pridávať i zložitejšie štruktúry ako menu…
LastHunter napsal(a):
Jasně, že to nefunguje, když změniš něco, co má dědit od Component, na jednoduchý string :) Navíc by ta továrnička měla vypadat, pokud se nemýlím, takto (pro použití v presenteru je určen
AppForm
a v jeho konstruktoru či pomocí metody presenteruaddComponent
ho s ním musíš svázat):
V novej továrničke zviazanie s rodičom nie je nutné – robí sa automaticky.
Pokud chceš vypsat něco jiného, než ten formulář, tak si musíš na to vytvořit komponentu či to nějak „hardcodnout“ do toho layoutu. Nemůžeš chtít po jedné továrničce, aby ti vracela vše :) Navíc, jakou logikou bys v ní zjišťoval, jestli chceš vrátit zrovna formulář nebo cokoli jiného?
Pravda je taká, že by mala vrátiť inštanciu implementujúcu IComponent, čo v praxi naozaj môže byť takmer čokoľvek…
- kravčo
- Člen | 721
grogy napsal(a):
Takhle :)
A jestli to chápu dobře, pak si totu svoji komponentu začlením do celé části co potřebuji například pomocí metody beforeRender() v BasePresenter, který budu dědit.
Nie. Továrnička je práve na to, aby komponent vytvorila a začlenila tam,
kam patrí. Povedzme, že chceš komponent nazvaný 'menu'
, musíš
mu napísať továrničku a tým by to malo končiť:
class BasePresenter extends Presenter
{
public function createComponentMenu()
{
$menu = new MyMenuControl;
$menu->setStructure(array(
'Novinky' => ...,
...
));
// alebo pomocou nastavenia v config.ini:
// $menu->setStructure(Environment::getConfig('menu'));
return $menu;
}
}
- grogy
- Člen | 147
Ah.. Super věc :) Děkuji kravco, moc jsi mi pomohl. A musím říci, že Component jsou skvělá hračka, zkusil jsem několik příkladů použití a krása. Pěkně Davide :)
Edit:// Pro vlastní komponentu formuláře (pomůže to s vykreslováním stejného formuláře do několika pohledů naráz). Stačí napsat komponentu, ve které je instance třídy Form. A pak šablonu kde si to navrhneme.
Editoval grogy (22. 7. 2009 19:32)