Component with name ‚XXX‘ does not exist

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

Zdravim,

ladenka hlasi chybu ‚Component with name 'MetaForm‘ does not exist.' pritom vse bych mel mit spravne.

tovarnicka:

<?php
function createComponentMetaForm()
{
	$form = new AppForm($this, 'meta_form');

	$form->addText('name', 'Název')
			->addRule(Form::FILLED, 'Vyplňte název!');

	$form->addSubmit('save', 'Uložit');

	$form->onSubmit[] = array($this, 'add');

	return $form;
}
?>

v sablone:

{control MetaForm}

Ja uz z toho pomalu zacinam sedivet, nekdo radu? :]

Editoval reflex (14. 12. 2009 18:32)

Ondřej Brejla
Člen | 746
+
0
-

Co třeba takto?

public function createComponentMetaForm($name) {
    $form = new AppForm($this, $name);
    $form->addText(‚name‘, ‚Název‘)->addRule(Form::FILLED, ‚Vyplňte název!‘);
    $form->addSubmit(‚save‘, ‚Uložit‘);

    $form->onSubmit[] = array($this, ‚add‘);
}

a

{control metaForm}
reflex
Člen | 28
+
0
-

Super, dnes vecer pred spanim se za tebe pomodlim! Dekuju :D

muzete tento topic smazat ;]

sodae
Nette Evangelist | 250
+
0
-

a k tomu název komponenty musí být totožný s názvem komponenty tedy ve výsledku

$form = new AppForm($this, 'metaForm');

první písmeno musí být malé !

Ondřej Brejla
Člen | 746
+
0
-

Pokud cpeš název už do konstruktoru, tak vždy radši z továrničky (jak jsem psal). To co sodae popisuje sice funguje, ale nemělo by se to radši používat. Nejhezčí je stejně verze s returnem :-)

Panda
Člen | 569
+
0
-

Koukám, že tu jsou menší nesrovnalosti kolem továrniček…

Jak již bylo naznačeno, u názvů komponent se rozlišuje velikost písmen. Pokud nechám komponentu připojit k presenteru automaticky (viz dále), je první písmeno vždy malé.

Další věc je připojení komponenty presenteru. V podstatě mám 2 možnosti, jak to udělat: ručně a automaticky. Ruční metoda znamená, že komponentě v konstruktoru uvedu jejího rodiče a její název – v takovém případě se komponenta k presenteru připojí ihned při vytvoření. Pokud se rozhodnu pro automatickou metodu, tak konstruktor zavolám bez těchto parametrů a pak objekt s komponentou vrátím. Presenter pak zkoumá, jestli navrácená komponenta již je připojená, nebo není. Pokud není, tak jí připojí pod příslušným názvem (první písmenko malé!) k presenteru.

Pokud bych to měl shrnout:
O připojení se starám sám – uvedu rodiče a název komponenty v konstruktoru a továrnička nemusí vracet nic. Příklad:

public function createComponentMetaForm($name) {
	$form = new AppForm($this, $name);
	// ...
}

O připojení se stará presenter (či jiný nadřazený kontejner) – rodiče ani název neuvedu a továrnička pak nově vytvořený objekt musí vrátit. Příklad:

public function createComponentMetaForm() {
	$form = new AppForm();
	// ...

	return $form;
}

// Úprava: na podnět hosiplana jsem se po pár měsících podíval na mechanismus vytváření komponent v aktuální verzi Nette a přibylo v něm pár kontrol, takže je to trochu jinak, než jsem původně psal. Pokud vyžádám komponentu MetaForm (velké písmenko na začátku), tak se žádná továrnička nevolá.

Jinak samotná tvorba komponent pomocí továrniček je velmi zajímavá. Podívejme se například na to, co se stalo v kódu, který způsoboval počáteční chybu…

Začněme makrem {control MetaForm}. Presenter je požádán o komponentu MetaForm. Nejdříve se podívá, jestli už neexistuje. Pokud opravdu neexistuje, tak přejde k procesu jejího vytvoření pomocí továrniček. Nejdříve se podívá po nějaké vhodné – najde createComponentMetaForm (!), protože u názvů funkcí v PHP nezáleží na velikosti písmen. V této továrničce se vytvoří komponenta a připojí se k presenteru pod názvem meta_form a továrnička tuto komponentu vrátí. Protože už továrnička již připojená je, tak se znovu nepřipojuje. Poté zkusí presenter vrátit komponentu MetaForm – ta ale neexistuje, protože továrna vytvořila komponentu meta_form.

Pokud bychom ale zavolali v šabloně {control meta_form}, tak aplikace skončí se stejnou chybovou hláškou – tentokrát se nenajde továrnička, protože se hledá funkce s názvem createComponentmeta_form.

Pokud změníme první řádek továrny na $form = new AppForm(); a necháme návratovou hodnotu, tak se o její připojení postará presenter. Ale ten jí připojí pod jménem metaForm, takže máme opět stejnou chybovou hlášku – komponenta s názvem MetaForm neexistuje.

Pokud bychom zmíněný řádek upravili na $form = new AppForm($this, 'MetaForm');, tak by vše mělo fungovat – komponentu s požadovaným názvem jsme si připojili sami.

Doufám, že můj příspěvek je srozumitelný a že alespoň někomu pomůže si záležitosti kolem továrniček v hlavě trochu urovnat.

Editoval Panda (14. 12. 2009 19:39)

romansklenar
Člen | 655
+
0
-

Pokud máte někdo čas, aktualizujte to v dokumentaci, dotazů tohoto typu je tu poslední dobou hodně. Je třeba ale proklikat celou dokumentaci, protože těch stránek kde jsou popsané komponenty je více

reflex
Člen | 28
+
0
-

Dekuji vsem, jeste bych doplnil co jsem vyzjistil

V tomto pripade muzu pouzit isSubmitted v ramci komponenty

<?php
    function createComponentMetaForm($name)
    {
	$form = new AppForm($this, $name);

	if (!$form->isSubmitted()) {
	   // nastaveni defaultnich hodnot
	}
?>

V tomto pripade to zarve ‚Form is not anchored and therefore can not determine whether it was submitted.‘

<?php
    function createComponentMetaForm($name)
    {
	$form = new AppForm();

	if (!$form->isSubmitted()) {
	   // nastaveni defaultnich hodnot
	}
?>

Tedy prvni varianta je asi ta „lepsi“

Panda
Člen | 569
+
0
-

Jen teda zrovna ty defaultní hotnoty je možné přes setDefaults() nastavit kdykoliv – formulář je po připojení k presenteru přepíše, pokud byl odeslán. :-)

reflex
Člen | 28
+
0
-

Panda napsal(a):

Jen teda zrovna ty defaultní hotnoty je možné přes setDefaults() nastavit kdykoliv – formulář je o připojení k presenteru přepíše, pokud byl odeslán. :-)

Pokazde az na ten priklad viz. vyse. Nebo by melo byt sparvne prirazovat hodnotu v renderXXX?

Panda
Člen | 569
+
0
-

Tak teď jsme se trochu nepochopili… Tím „kdykoliv“ jsem myslel i za situace, kdy je formulář odeslán, tzn. ta kontrola na isSubmitted() je zde zbytečná:

<?php
function createComponentMetaForm()
{
        $form = new AppForm();

	// nastaveni defaultnich hodnot

	return $form;
}
?>

Co se nastavování hodnot týče, tak by dle mého soudu mělo být v tom místě, kde načítáš data z databáze. A to je většinou v render<view>(). Jinak je to ale asi celkem jedno, pokud to člověk bude dodržovat všude.

Ale to už jde trochu mimo téma…

Patrik Votoček
Člen | 2221
+
0
-

Takže která z variant:

public function createComponentFooForm($name)
{
	$form = new \Nette\Application\AppForm($this, $name);
	//...
}
// nebo/vs.
public function createComponentFooForm()
{
	$form = new \Nette\Application\AppForm();
	//...
	return $form;
}

Se dá považovat za best practice?

Ondřej Mirtes
Člen | 1536
+
0
-

Ta druhá ;)