redirect z komponenty ven

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

Snažil jsem se zavolat v komponentě redirect, který směřoval ven z ní, ale vždy to skončilo chybou, že komponenta se jménem xxx neexistuje.
Konkrétně mám control Poll, po hlasování se volalo

$this->redirect('this');

Takže se načte zase původní stránka odkud se hlasovalo.

Já bych ale chtěl po hlasování přejít na presenter Poll a vypsat všechny ankety. Tedy něco jako

$this->redirect('Poll:showAll');

V tomhle okamžiku mi laděnka zahlásí, že komponenta Poll neexistuje. Zkoušel jsem i další varianty jako

:Poll:showAll

:Front:Poll:showAll

Poll:showAll

Front:Poll:showAll

ale všecho končilo podobnou chybou, že komponenta xxx neexistuje.

Pak jsem si ale uvědomil, že komponenta o nějakém presenteru Poll vůbec nemá vědět, takže jak z toho ven?
Napadlo mě předávat si do komponenty callback do presenteru kde je továrnička a tam provést klasický redirect na jiný presenter.

Mám dvě otázky:

  1. lze z komponenty volat redirect na nějaký presenter?
  2. jak by se to dalo řešit správně, tedy když vezmu v úvahu, že komponenta neví o okolním světě
Tharos
Člen | 1030
+
0
-

Z kontextu komponenty by mělo fungovat $this->presenter->redirect('Poll:showAll'), vyzkoušej to.

Editoval Tharos (21. 9. 2011 9:33)

Foowie
Člen | 269
+
0
-

$this->getPresenter()->redirect("Poll:showAll");

Bertram
Člen | 75
+
0
-

Ahoj, redirect musíš volat nad presenterem.

$this->getPresenter()->redirect('this'); // ('Poll:showAll')
// nebo
$this->presenter->redirect('this'); // ('Poll:showAll')

edit: pozdě, ale v jednom :)

Editoval Bertram (21. 9. 2011 9:36)

Filip111
Člen | 244
+
0
-

všem díky, takovéhle volání funguje

Teď by mě ale ještě zajímala odpověď na tu druhou otázku – komponenta přece neví že existuje nějaký presenter Poll, resp. si myslím, že komponenta by měla být vždy univerzální a neměl by se v ní volat jiný presenter.

Jak vyřešit redirect teď?

Foowie
Člen | 269
+
0
-

Nevím, jak složité to je, ale vždycky můžeš do komponenty přidat metodu ->setRedirectLink($link), nebo podobně a nechat jí naplnit presenterem v továrničce ;)

Filip111
Člen | 244
+
0
-

ok, takže uvažuji správně…

Jan Suchánek
Člen | 404
+
0
-

Do komponenty tedy předáváte presenter?

protected function createComponentExample($name){
	return new ExampleControl($this, $name);
}

nebo jak kdy?

smasty
Člen | 90
+
0
-

@jenicek: Komponenta je vždy k presenteru pripojená, inak by sa ani nedala použiť. Pripojenie je možné dvomi (tromi) spôsobmi:

  1. V konštruktore: new MyControl($this, $name)
  2. Pomocou addComponent(): $presenter->addComponent(new MyControl, 'myControl') – toto spraví predchádzajúca možnosť automaticky
  3. Magicky pomocou továrničky – stačí aby továrnička vracala (return) danú komponentu a tá sa automaticky pripojí.

K presenteru sa potom z každej pripojenej komponenty dostaneš pomocou $component->getPresenter();

Takže odpoveď na tvoju otázku: Nie vždy ho treba predávať v konštruktore, väčšinou stačí aj v továrničke pomocou return.

22
Člen | 1478
+
0
-

smasty: to není tak úplně pravda imho:

  1. Control se připojí hned do stromu komponent
  2. Tohle by se nemělo používat
  3. Control se připojí až v momentě, kdy se volá

takže záleží, kdy potřebuješ mít $this->presenter v Controlu dostupný…

Jan Suchánek
Člen | 404
+
0
-

smasty: Super, tak trošku mi to je jasný.

Magicky, jak to přesně myslíš? něco jako?

// To je asi pěkná békovina :)
protected function createComponentExample($name){
        return $this->myControl;
}

public function getMyControl($name){
	return new MyControl($this, $name);
}

Jak řešíte cashování? jen v šabloně, v presenteru i v komponentě? Díky

Editoval jenicek (7. 10. 2011 11:46)

Filip Procházka
Moderator | 4668
+
+1
-

22 napsal(a):

2. Tohle by se nemělo používat

Proč ne?

jenicek napsal(a):

Magicky, jak to přesně myslíš? něco jako?

Co to je za splácaninu ? :P

Připojovat komponenty můžeš takto

$this['jmeno'] = new MyControl();

Zcela ekvivalentně takto

$this->addComponent(new MyControl(), 'jmeno');

Pomocí továrničky konstruktorem

protected function createComponentJmeno($name)
{
	new MyControl($this, $name);
}

Pomocí továrničky returnem

protected function createComponentJmeno()
{
	return new MyControl;
}

Všechny jsou úplně v pořádku. Osobně preferuji poslední zápis.

Rozdíl je mezi nimi podle toho kdy máš $this->presenter přístupný. Pokud předáváš presenter do konstruktoru, je přístupný už v konstruktoru. Jinak až po připojení do presenteru.

cachování si přečti zde.

Editoval HosipLan (6. 10. 2011 17:55)

22
Člen | 1478
+
0
-

HosipLan: měl jsem to nějak zafixované z dokumentace (konec odstavce).. ale důvod už neznám. Nicméně v nové dokumentaci nic takového není…

Filip Procházka
Moderator | 4668
+
0
-

To napsal Patrik a pravděpodobně proto, že je jednodušší si pamatovat přidávání přes ArrayAccess. Tenhle způsob je naprosto v pořádku.

Jan Suchánek
Člen | 404
+
0
-

HosipLan: super jako vždy, dík