Připojení stejné části webu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
grogy
Člen | 147
+
0
-

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
+
0
-

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}

jasir
Člen | 746
+
0
-

No jasně, na1k má pravdu, přes komponenty. Na tom stojí Nette.

Jod
Člen | 701
+
0
-

Trošku poopravím na1k. By som skôr povedal, že ti stačí vytvoriť formulár v BasePresenteri (createComponentForm) a volať ho v šablone {control form}. Mať v controíle čistý formulár je trochu zbytočné.

grogy
Člen | 147
+
0
-

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
+
0
-

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
+
0
-

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?

grogy
Člen | 147
+
0
-

Jasný, můj zkrat + hlavně neznalost.

Jde mi o to, jak to vkládat co nejlépe, ať už se jedná o formulář, či menu, které se generuje z databáze. – Jak to řešíš ty. Vlastní komponentou?

kravčo
Člen | 721
+
0
-

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 presenteru addComponent 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…

grogy
Člen | 147
+
0
-

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()BasePresenter, který budu dědit.

kravčo
Člen | 721
+
0
-

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()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
+
0
-

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)