#1 11. 6. 2009 23:26

Jan Tvrdík
Nette guru
Místo: Prostějov
Registrovaný: 13. 4. 2008
Příspěvky: 604
Web

Vylepšená továrnička: create<componentName>($name)

Poznámka: je součástí frameworku od verze 0.9

Vytahuji vylepšenou továrničku, protože mi přijde škoda, že zapadla.

protected function createComponent($name)
{
        if (String::lower($name) === 'component') {
                throw new InvalidArgumentException("Argument name '$name' is not allowed.");
        }

        $method = 'create' . $name;

        if (method_exists($this, $method)) {
                $component = call_user_func(array($this, $method));

                if ($component instanceof IComponent && $component->getParent() === NULL) {
                        $this->addComponent($component, $name);

                } elseif ($component->getParent() === NULL) {
                        is_callable(array($this, $method), TRUE, $textual);
                        throw new InvalidStateException("Function '$textual' must return instance of IComponent");
                }

        } else {
                parent::createComponent($name);
        }
}

Offline

 

#2 11. 6. 2009 23:58

PaBi3
Člen
Místo: Bratislava
Registrovaný: 27. 3. 2009
Příspěvky: 36

Re: Vylepšená továrnička: create<componentName>($name)

Ja by som navrhol naozaj len takú kozmetickú úpravu a tou je výmena pomalšieho String::lower() za rýchlejšie strtolower(). Veď kto už použije v názve komponent diakritiku s veľkými písmenami?

Offline

 

#3 12. 6. 2009 0:25

nAS
Nette guru
Místo: Praha
Registrovaný: 18. 12. 2008
Příspěvky: 210
Web

Re: Vylepšená továrnička: create<componentName>($name)

Je vůbec nějaký důvod, proč se tahle verze nepoužije v distribuci? Podle mě je výrazně lepší.


$application->run(); // Run Forrest, run!

@MartinMajor

Offline

 

#4 12. 6. 2009 9:17

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

Taky by se teoreticky u komponenty s názvem component mohla zavolat metoda parent::createComponent. Otázka je, jestli to něco řeší, když tahleta továrnička stejně bude většinou v BasePresenteru.

Offline

 

#5 16. 6. 2009 22:38

Inza
Nette guru
Místo: Praha
Registrovaný: 8. 7. 2008
Příspěvky: 351
Web

Re: Vylepšená továrnička: create<componentName>($name)

Je tahleta továrníčka už v Nette/Extras v doku? Pokud ne, dáte ji tam pls?

Offline

 

#6 16. 6. 2009 23:11

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

To je otázka, co třeba tam dát tuhletu skoro stejnou? :-D

/**
 * Create component using create{Name} method
 * @param string $name
 */
protected function createComponent($name) {
        $method = "create" . $name;

        if (method_exists($this, $method) && strtolower($name) !== "component") {
                $component = call_user_func(array($this, $method), $name);

                if ($component instanceof IComponent && $component->getParent() === NULL) {
                        $this->addComponent($component, $name);
                }

        } else {
                parent::createComponent($name);
        }
}

Offline

 

#7 29. 6. 2009 16:31

jasir
Nette guru
Místo: Praha
Registrovaný: 4. 12. 2008
Příspěvky: 626

Re: Vylepšená továrnička: create<componentName>($name)

Jenom chci nahlásit, že supertovárnička je boží.

Společně s novým macrem {widget} (které odstraní přebytečné render… metody, ve kterých se jen plnila template komponentami) se některé prezentery smrsknou jen na createMyControl() metody, coz je fakt jako cool.

Offline

 

#8 29. 6. 2009 17:57

Honza Kuchař
Moderator
Místo: Brno
Registrovaný: 12. 8. 2007
Příspěvky: 1285
Web

Re: Vylepšená továrnička: create<componentName>($name)

Proč tahle perfektní věc ještě není v distribuci?

Offline

 

#9 6. 7. 2009 17:43

romansklenar
Moderator
Místo: Ostrava
Registrovaný: 20. 7. 2008
Příspěvky: 769
Web

Re: Vylepšená továrnička: create<componentName>($name)

Protože není problém udělat CTRL + C a CTRL + V do BasePresenteru nebo BaseControlu, když většinou stejně nějaký základní presenter je? :)

Továrnička createComponent je jen obecný mechanismus a neurčuje konkrétní implementaci. Jestli si to člověk naimplementuje přes switche, podmínky nebo přes toto je přece jen čistě na něm. Začátečníky by mohlo volání callbacků dost zmást, proto si myslím že je i dobře, že to není v distribuci.

Offline

 

#10 6. 7. 2009 18:39

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

Stejně jako by je mohlo zmást volání action{Action} :)

Ale přišel jsem na jiné proti… Muselo by se každému vysvětlit, aby se nepokoušel zavolat třeba $this->getComponent("template"), což pravda normálně nikoho ani nenapadne.

Offline

 

#11 6. 7. 2009 19:28

jasir
Nette guru
Místo: Praha
Registrovaný: 4. 12. 2008
Příspěvky: 626

Re: Vylepšená továrnička: create<componentName>($name)

romansklenar napsal(a): Začátečníky by mohlo volání callbacků dost zmást, proto si myslím že je i dobře, že to není v distribuci.

Mě se zdá, že by to začátečníky určitě nemátlo, protože pak by „Návod na použití component v presenteru“ scvrkl na toto:

  1. Pro každou komponentu, kterou chceš použít v presenteru, vytvoř metodu createMyControl (nebo pro formuláře createMyForm), která vytvoří a vrátí nakonfigurovanou komponentu/formulář
  2. V template vykresli komponentu pomocí {control MyForm} nebo {wiget MyControl:specialRender}
  3. Pokud je zapotřebí dále manipulovat s komponentami například v renderView(), komponentu získáte pomocí $this->getControl('myForm')

Presenter se tedy za pomoci {widget} a této továrničky smrskne (v ideálním případě) do metod createMyControl()

Honza M. napsal(a): Ale přišel jsem na jiné proti… Muselo by se každému vysvětlit, aby se nepokoušel zavolat třeba $this->getComponent("template"), což pravda normálně nikoho ani nenapadne.

Dobrá připomínka, jméno komponenty ‚template‘ by v ‚createMyControl()` mělo být asi zakázané stejně jako 'component‘.

Editoval jasir (6. 7. 2009 19:31)

Offline

 

#12 7. 7. 2009 10:19

PetrP
Moderator
Místo: Praha
Registrovaný: 15. 7. 2008
Příspěvky: 610
Web

Re: Vylepšená továrnička: create<componentName>($name)

Dale existuje jeste createRequest.

Co kdyby jsme se vyhli vsech tehle problem s create*, protoze muzu v kodu pouzivat jeste dalsi createCokoli. A pouzit control<Name>, nebo component<Name>, nebo widget<Name> ?

Offline

 

#13 7. 7. 2009 10:40

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

Asi nejvýstižnější by bylo createComponent<Name>, ale je to dost dlouhé.

Offline

 

#14 7. 7. 2009 10:47

jasir
Nette guru
Místo: Praha
Registrovaný: 4. 12. 2008
Příspěvky: 626

Re: Vylepšená továrnička: create<componentName>($name)

Honza M. napsal(a):

Asi nejvýstižnější by bylo createComponent<Name>, ale je to dost dlouhé.

Nebo zavést podtržítko…

<?php
protected function create_MyForm()
protected function create_MyWidget()
?>
  • Pro: větší přehlednost, jasné odlišení widgetových továrniček, nikdy se nebude tlouct s Nette
  • Proti: nehezké

Editoval jasir (7. 7. 2009 10:48)

Offline

 

#15 7. 7. 2009 17:52

PetrP
Moderator
Místo: Praha
Registrovaný: 15. 7. 2008
Příspěvky: 610
Web

Re: Vylepšená továrnička: create<componentName>($name)

jasir napsal(a):

Nebo zavést podtržítko…

To je proti Nette konvencím:

Coding standard

Functions and Methods

  • camelCase

Honza M. napsal(a):

Asi nejvýstižnější by bylo createComponent<Name>, ale je to dost dlouhé.

To je popravdě nejvýstižnější, otázka je: je to create skutečně nutné?

Offline

 

#16 8. 7. 2009 17:01

David Grudl
Administrator
Registrovaný: 8. 2. 2005
Příspěvky: 4050
Web

Re: Vylepšená továrnička: create<componentName>($name)

Do frameworku je lepší nové věci přidávat teprve v okamžiku, když ostatním tak moc chybí, že vyhrožují fyzickým útokem nebo úplatkem :-)

Ale jo, přidat by se to mohlo. Na úrovni ComponentContainer ne, na úrovni Control by to mohlo být ideální. Nicméně název by měl být dostatečně bezpečný a srozumitelný, což znamená createComponent<Name>.

Offline

 

#17 8. 7. 2009 17:38

David Grudl
Administrator
Registrovaný: 8. 2. 2005
Příspěvky: 4050
Web

Re: Vylepšená továrnička: create<componentName>($name)

Offline

 

#18 9. 7. 2009 10:17

Jod
Nette guru
Registrovaný: 24. 9. 2008
Příspěvky: 790
Web

Re: Vylepšená továrnička: create<componentName>($name)

Super díky. Nebolo by lepšie keby sa po zavolaní getComponent(‚grid‘) zavolalo createComponentGrid, miesto createComponentgrid? Alebo najprv skúsila zavolať prvá alternatíva a ak by sa nenašla tak druhá?


Všetko je v Akrabat.forms v examples distribúcie. Zomg, puff..

Offline

 

#19 9. 7. 2009 11:04

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

Vždyť to volání metod není citlivé na velikost písmen.

Offline

 

#20 9. 7. 2009 11:59

Jod
Nette guru
Registrovaný: 24. 9. 2008
Příspěvky: 790
Web

Re: Vylepšená továrnička: create<componentName>($name)

Potom už asi debilniem z tejto roboty :)


Všetko je v Akrabat.forms v examples distribúcie. Zomg, puff..

Offline

 

#21 10. 7. 2009 15:51

Honza Marek
Moderator
Místo: Kladno
Registrovaný: 31. 3. 2007
Příspěvky: 1281
Web

Re: Vylepšená továrnička: create<componentName>($name)

Hlásim nespokojenost s implementací chytřejší továrničky.

Potřeboval bych metodám createComponent<Name> předávat parametr $name, protože některé moje komponenty potřebují již v továrničce být připojené k presenteru.

Př.:

// v presenteru
protected function createComponentEditForm($name) {
        new PageForm($this, $name);
}

// PageForm.php
class PageForm extends AppForm {
        public function __construct($parent, $name) {
                parent::__construct($parent, $name);

                // definice
                ...

                $this["id"]->setValue = $this->presenter->getParam("id");
        }
}

Pokud by tenhle ne úplně šťastný příklad jako argument nestačil, zamyslím se a vymyslím lepší.

Offline

 

#22 10. 7. 2009 15:57

romansklenar
Moderator
Místo: Ostrava
Registrovaný: 20. 7. 2008
Příspěvky: 769
Web

Re: Vylepšená továrnička: create<componentName>($name)

Nepůjde to získat přes reflection z názvu metody? Ikdyž chápu, že je to zbytečně složité.

Offline

 

#23 10. 7. 2009 18:07

LM
Nette guru
Registrovaný: 11. 3. 2008
Příspěvky: 254

Re: Vylepšená továrnička: create<componentName>($name)

Proč to $this["id"]->setValue() nezavolat až v attached?

// class PageForm
protected function attached($presenter)
{
        parent::attached($presenter);

        if ($presenter instanceof Presenter) {
                $this["id"]->setValue = $presenter->getParam("id");
        }
}

Editoval LM (10. 7. 2009 18:07)

Offline

 

#24 10. 7. 2009 19:12

Jod
Nette guru
Registrovaný: 24. 9. 2008
Příspěvky: 790
Web

Re: Vylepšená továrnička: create<componentName>($name)

Honzo, keď napíšeš createComponentEditForm, tak je jasné, že komponenta sa musí volať editForm, inak sa ti ta fnc nezavolá. Ale tiež si myslím, že ten parameter by nebol na škodu, predsa je to krajšie keď tam dám $name, než napevno string. xixi =))


Všetko je v Akrabat.forms v examples distribúcie. Zomg, puff..

Offline

 

#25 11. 7. 2009 22:56

PetrP
Moderator
Místo: Praha
Registrovaný: 15. 7. 2008
Příspěvky: 610
Web

Re: Vylepšená továrnička: create<componentName>($name)

Jsem pro přidání, protože:

  • při případném přejmenování ho změním na méně místech ;]
  • méně psaní ;]
  • můžu používat továrny na některé componenty (nebo jejich častí nastaveni, vytvoření)
  • tahat si componenty z modelu (porad bojuju s myšlenkou ze tam např Form patří)
  • dostane název case sensitive tak jak jsem si ho napsal v getComponent
  • snadněji se mi migruje ze starého způsobu přes createComponent($name) { switch ($name) ....
  • něco si můžu například kešovat (nebo mít v sesions) v namespace podle nazvu componenty.
  • parametr bude nepovinej, takže ho použiju jen když ho potřebuju.

Editoval PetrP (11. 7. 2009 22:58)

Offline

 

Zápatí