Zacyklení při odstraňování komponenty

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

Ahoj narazil jsem na nekonečný cyklus :( Mám následující kód:

function createComponentTabs($name){
    $tc = new TabControl($this,$name);
    $this->removeComponent($tc); // <-- tady se to zacyklí
	// A zde bych vrátil jinou componentu
}

Přišel jsem na to, že se to zacyklí na řádku, kde se ověřuje zda je componenta registrovaná u svého rodiče.
ComponentContainer.php:120 removeComponent() vytuhne na řádku 128
V Component.php:226 jak je getComponent, tohle způsobí nekonečný cyklus.

Poslední rev. nette

romansklenar
Člen | 655
+
0
-

A není to blbost odebírat komponentu hned potom, co se vytvoří a připojí k rodiči?

PetrP
Člen | 587
+
0
-

Blbost to je ;] To nic ale nemění na faktu že by se to nemělo cyklit.

Místo removeComponent, si nepřipojuj k rodiči hned v konstructoru ale až později přes addComponent.
Ale ještě lepší by bylo takovýhle čachry nedělat.

Honza Kuchař
Člen | 1662
+
0
-

No v podstatě ano. Ale zacyklit by se to nemělo. Kód který jsem sem dal je samozřejmě jen ukázkový, popíšu proč to dělám.

Mám formulář, který pokud není odeslán (je voláno isSubmitted(), tzn. form musí být připojen k rodiči), tak se kontroluje zda byl předán nějaký parametr. Pokud není, tak chci vrátit jinou komponetu. Ale před tím musím odstranit ten form. (Componenta musí mít stejný název – tohle se totiž odehrává v továrničce)

function create...(){
 $form = new AppForm(...);
 if(!$form->isSubmitted()){
   if(!$this->getParam("test")){
     $this->removeComponent($form);
     $component = new ...;
     return $component;
   }
 }
},

Jak byste to řešili vy? Jak se tak dívám, tak je to docela prasárna. Továrnička by asi měla vracet vždy tu samou componentu. Takže asi vytvořit componentu?

Honza Kuchař
Člen | 1662
+
0
-

Opravdu komponenta bude nejelegantnější.

PetrP
Člen | 587
+
0
-

Předpokládám že to máš pro nějakou vícekrokovou registraci že?

Bych to rozdělil do několika component, a logiku přesunul do presenteru

function createComponentKrok1();
function createComponentKrok2();

function renderDefault()
{
	 if($this->getParam("krok") == self::KROK_1)
		$this->template->krokForm = $this['krok1'];
	else if($this->getParam("krok") == self::KROK_2)
		$this->template->krokForm = $this['krok2'];
}

Nemusíš pak řešit jestli byl/nebyl odeslanej, protože tak jako tak se k němu to odeslání dostane. Posun o krok bych dal až v onSubmit_krok1 (tedy kdyz byl předchozí validně odeslán).

Nebo jak píšeš to celé umístit ještě do jiné komponenty která to bude řešit sama, mimo presenter.

Třeba něco jako

function createComponentKrokForm()
{
	$c = new KrokovaRegistrace($this,$name);
	$c->krok[] = $this['krok1']; // i když je zbytečně si vytvářet componentu když ji nepotrebujes, ty už si to ale nějak naimplementuješ dobře ;]
	$c->krok[] = $this['krok2'];
}

Editoval PetrP (5. 8. 2009 9:39)

Honza Kuchař
Člen | 1662
+
0
-

Díky moc za odpověď. Zase je mi to o něco jasnější. Řeším to u toho TabControlu (dneka ho sem snad přidám). Přidám tam callbacky na rendrování jednotlivých obsahů tabů a bude to naprosto v pohodě. ;)

David Grudl
Nette Core | 8228
+
0
-

zacyklení fixed