Metoda isSignalReceiver() v komponentách

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

Často potřebuju zjišťovat, je-li komponenta příjemcem určitého signálu a tuto funkčnost si do komponent vždycky dopisuju:

class BaseControl extends Control
{
	...

	/**
	 * Checks if component is signal receiver.
	 * @param  string  signal name
	 * @return bool
	 */
	public function isSignalReceiver($signal = TRUE)
	{
		return $this->getPresenter()->isSignalReceiver($this, $signal);
	}
}

Protože je to jednořádková implementace, napadlo mě, že by se dala použít rovnou v PresenterComponent nebo by tato metoda mohla být součástí rozhraní ISignalReceiver.

romansklenar
Člen | 655
+
0
-

Toto řešení má v momentálním stavu frameworku jednu nevýhodu – po zpracování signálu už ji nelze spolehlivě použít, protože se v presenteru mažou stopy o obdrženém signálu poté co je zpracován.

Proto se chci zeptat – je nutné nulovat tuto proměnou? Zkusil jsem si v aplikacích tento řádek v presenteru zakomentovat a nepozoruju v nich žádné chyby.

David Grudl
Nette Core | 8218
+
0
-

Je to z toho důvodu, že signál lze zpracovat už dříve (např. během metody action<Action>()) a aby se poté nezpracoval znovu, proměnná se vynuluje.

Asi by to šlo řešit jinak – ale spíš se zeptám, pro jaký případ to následně zjišťovat potřebuješ?

ad metoda isSignalReceiver: to je dobrý nápad, jen bych musel přejmenovat metodu Presenter::isSignalReceiver na Presenter::isComponentSignalReceiver (což by asi bylo vhodné). Tedy aby chování isSignalReceiver bylo stejné pro všechny komponenty, včetně presenteru.

romansklenar
Člen | 655
+
0
-

Aha, hned je to jasné :) díky za reakci.

V podstatě je důvod stejný jako tady, jen je to jiné čistější řešení, které mě napadlo, protože vlákno zůstalo mrtvé.

Používám to v datagridu na pár místech, ale před vykreslením už se to nedá spolehlivě použít (ikdyž toto není zrovna nejlepší příklad, protože na formuláři by se to dalo nahradit pomocí $this->getForm()->isSubmitted()).

Na formuláři ale nemůžu při jeho vytváření použít isSubmitted() protože pokud si dobře vzpomínám, nebyly pak v $form->getValues() všechna data správně (isSubmitted() v takové případě volá processHttpRequest() a tam k tomu myslím docházelo – teď mě napadá jestli nejde o nějakou zákeřnou chybu – ještě ověřím). Takže nebyl způsob jak při vytváření formuláře spolehlivě zjistit, jestli je příjemcem signálu 'submit' a podle toho pak ovlivnit jeho generování.

Každopádně pro Controly by se mohlo při nějakých složitějších aplikacích hodit oveření i v pozdějších fázích životního cyklu, jestli příjímala ten a ten signál.

romansklenar
Člen | 655
+
0
-

Takže to s tím formulářem potvrzuju – pokud je voláno isSubmitted() v továrničce kde je vytvářen a je volán z presenteru, protože přijímá zrovna signál submit, tak to naruší odeslaná data.

Není tedy způsob jak bez vedlejších efektů při vytváření formuláře továrničkou zjistit, jestli byl i odeslán.

Šlo by tedy zapracovat úpravu, kterou jsi navrhoval o 2 příspěvky výše? Mám napsat path?

David Grudl
Nette Core | 8218
+
0
-

Nebylo by lepší místo isSignalReceiver(...) udělat getSignal()?

romansklenar
Člen | 655
+
0
-

Na názvu moc nesejde. Důležité je, aby bylo v Nette jak ověřit, zda-li je komponenta příjemcem signálu i ve vykreslovací fázi životního cyklu.

David Grudl
Nette Core | 8218
+
0
-

Bude to trošku složitější, ale dám to tam.

Honza Kuchař
Člen | 1662
+
0
-

Ahoj, napsal jsem si tedy metodu isSignalReceiver pro komponenty. Ale nevím jestli dělá přesně to co měla dělat ta původně zamýšlená fce.

/**
 * Is $component receiver of $signal?
 *
 * @param PresenterComponent $component
 * @param string $signal
 * @return bool
 */
function isSignalReceiver(PresenterComponent $component,$signal){
    $_signal = $this->presenter->getSignal();
    if($_signal[0]==$component->getUniqueId() and $_signal[1]==$signal)
        return true;
    else
        return false;
}

Pokud to někomu pomůže budu, rád. Pokud je to úplně mimo, tak mi prosím řekněte. Já to smažu. :)