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

před 11 dny

baraja
Člen | 9
+
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. 16:07)

před 11 dny

CZechBoY
Člen | 3377
+
+1
-

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

před 11 dny

baraja
Člen | 9
+
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.

před 11 dny

jiri.pudil
Člen | 870
+
+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 :)

před 11 dny

Felix
Nette Core | 937
+
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.

před 7 dny

Mabar
Člen | 73
+
+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. 13:24)