Automatické propojení komponenty s aktuálním presenterem

baraja
Nette Blogger | 29
+
0
-

Ahoj,

narazil jsem na pro mě zajímavé chování komponent, které sice chápu, ale stejně přemýšlím, jestli je chování opravdu očekávané a případně jak by šlo vylepšit.

Dejme tomu, že mám administraci, která se skládá z desítek komponent, které se dynamicky načítají a jsou uloženy uvnitř balíků, aby se s nimi dobře pracovalo. Komponenty jsou definovány jako služby DIC.

V BasePresenteru se stane nějaká magie vyhledání komponent pro aktuální stránku. Zkrátit by to šlo třeba na:

public function startup(): void
{
	parent::startup();
	/** @var SeoControl $seoControl */
	$seoControl = $this->context->getByType(SeoControl::class);
	dump($seoControl);

	// Vyhodí výjimku: Component of type 'SeoControl' is not attached to 'Nette\Application\UI\Presenter'.
	$seoControl->generateTestLink();

	$seoControl->setParent($this);
	// Funguje
	$seoControl->generateTestLink();
}

Uvnitř SeoControl je implementace metody následující (hodně zjednodušeno):

class SeoControl extends Control implements DynamicComponent
{

	public function generateTestLink(): void
	{
		dump($this->hasPresenter());
		try {
			dump($this->presenter->link('this'));
		} catch (\Exception $e) {
			dump($e);
		}
	}

}

Otázky:

  1. To, že se ke komponentě automaticky nepřikládá aktuální presenter je záměr?
  2. Pokud ano, je volání setParent() na všech místech aplikace opravdu potřeba?
  3. Co udělat možnost v neonu nastavit, aby se ke všem komponentám automaticky přidával parent aktuální presenter? Případně existuje něco takového? Obvykle se komponenty totiž vykreslují v presenterech a neustálé předávání parenta je otravné.
  4. To, že se má vložit aktuální presenter by o sobě mohla komponenta říct splněním nějakého rozhraní.

Pokud úprava automatického předávání aktuálního presenteru do komponenty (co je služba) dává smysl, klidně to implementuji a pošlu pull request.

Díky.

Editoval baraja (8. 8. 2019 16:07)

CZechBoY
Člen | 3608
+
+1
-

Komponenta dostane presenter pokud ji pridas v presenteru pres addComponent… takhle jen vytvoris „nejakej“ objekt mimo nette

baraja
Nette Blogger | 29
+
0
-

@CZechBoY Ano, to popisuješ jen jinými slovy to, na co jsem se původně ptal.

Otázka ale byla, jestli by Nette mohlo automaticky řešit přidání relace na presenter (nebo aspoň v některých případech), protože pokud chci například přesměrovat uživatele, tak to není možné.

Díky.

jiri.pudil
Nette Blogger | 1028
+
+2
-

Nette to řeší, ale jen pokud použiješ jeho komponentový systém, tj. buďto ručním přidáním komponenty, jak píše @CZechBoY, anebo více automaticky pomocí createComponent*(). Velmi dobře o tom píše dokumentace :)

Felix
Nette Core | 1186
+
0
-

Jeste doplnim, ze volanim setParent se provadi black-magic ohledne tzv. monitoru, alias volani $this->monitor(trida::class, cb(), cb()). S tim velmi opatrne.

Marek Bartoš
Nette Blogger | 1165
+
+1
-

Dělej to přes createComponent, jak jsme se bavili a nebudeš mít problém ;)
A jak psal Felix, setParent je spíš internal. Měl bys připojovat komponentu k rodiči, ne rodiče ke komponentě. Takže třeba $this['seo'] = $control, když už teda createComponent nepoužiješ

Editoval Mabar (12. 8. 2019 13:24)