Jak zjistit název komponenty

Phalanx
Člen | 310
+
0
-

Ahoj, už se několik hodin nehorázně trápím, takže vás chci požádat o pomoc. Mám komponentu, která obsahuje několik dalších komponent (jmenovitě Datagrid, co obsahuje komponenty – filtr, tabulka, paginator).

Chci data z filtru ukládat do session, ale potřebuju zjistit název aktuální komponenty. Vůbec netuším, do které části bych měl dát tento kód. Chtěl jsem ho mít už nejlíp v konstruktoru, ale tam je název komponenty null.

<?php
	$name = $this->getName();
	$this->sessionSection = $this->session->getSection("grid-{$name}");
?>

Snažil jsem se ještě hledat „životní cyklus komponenty“ i procházet přímo zdrojáky Nette. Zkoušel jsem i metodu attached.

CZechBoY
Člen | 3608
+
+2
-

V konstruktoru jméno komponenty ještě není, nejdřív v attached stavu (tedy po připojení k presenteru). V konstruktoru se můžeš přihlásit k odebírání události onAnchor, což je událost vyvolaná po připojení komponenty k presenteru.

public function __construct()
{
	$this->onAnchor[] = function() {
		$componentName = $this->getName();
	};
}

Možná ještě lepší bys měl ukládat si $this->getUniqueId(). https://api.nette.org/…ent.php.html#…

edit: upraven název eventu podle @DavidGrudl

Editoval CZechBoY (13. 10. 2018 18:16)

David Grudl
Nette Core | 8082
+
+4
-

Je to onAnchor

CZechBoY
Člen | 3608
+
0
-

@DavidGrudl pravda, já jsem si už dřív u sebe pojmenoval event jinak tak mě to zmátlo. Jdu to předělat :-)

Phalanx
Člen | 310
+
0
-

Děkuju vám oběma, hodně mě to posunulo. Použil jsem onAnchor plus jsem přidal do Presenteru $this->addComponent($grid, $name);, abych komponentu zaregistroval dřív a funguje. (pokud by existoval elegantnější způsob, klidně mě poučte).


Poslední věc co mi tu ještě nejde je, že mám chybně pořadí requestů. Mám tuto strukturu komponenty:

  1. Grid
    1. Filtr
    2. Paginator atd.

Takže když odešlu filtr, pak se nejdřív vykreslí Grid a pak až se vykoná onSuccess u formuláře Filtru. Jde tohle nějak obejít prosím?

Výsledek tedy je, že se filtruje jakoby až po druhém requestu.


Když odešlu FilterForm, volá se pořadí:

  1. Presenter: createComponentEmailsGrid
  2. EmailsGrid: createComponentFilterForm
  3. EmailsGrid: createComponentFilterForm:onFormSave

Potřeboval bych vyvolat jen onFormSave a ne celou strukturu.

<?php

SomePresenter extends Presenter
{
	protected function createComponentEmailsGrid($name)
	{
		$grid = $this->iGridControlFactory->create();
		$this->addComponent($grid, $name);
		$filter = $grid->getFilterValues();
		return $grid;
	}
}



// IGridControlFactory...


class GridControl extends Control
{
	public function __construct(
		Session $session
		// ...
	) {
		// ...
		$this->session = $session;

		$this->onAnchor[] = function() {
			$this->sessionSection = $this->session->getSection($this->getUniqueId());
		};
	}



	public function createComponentFilterForm()
	{
		$form = $this->filterFormControlFactory->create();
		// ...
		$form->setDefaults($this->getFilterValues());


		$form->onFormSave[] = function (Form $form) {

			if ($form['filter']->isSubmittedBy()) {
				$values = $form->getValues(true);
				$this->setFilterValues($values);
			}

			if ($this->getPresenter()->isAjax()) {
				$this->redrawControl('grid');
				$this->redrawControl('gridFilter');
			} else {
				$this->redirect('this');
			}
		};

		return $form;
	}
}

?>

Editoval Phalanx (14. 10. 2018 13:39)

CZechBoY
Člen | 3608
+
0
-

Grid by se měl vykreslit s novým filtrem rovnou při tom jednom submit requestu. Pokud se tak neděje tak bereš filtry z úložiště dřív než se tam uloží a problém bude imho někde jinde mimo tenhle kod.

Phalanx
Člen | 310
+
0
-

@CZechBoY Díky, jdu teda zkoušet dál. Myslel jsem si, že tohle způsobuje komponenta v komponentě (filtr komponenta je v grid komponentě).


Edit: Zjistil jsem, že pokud navážu komponentu do Presenteru dřív, tak si tím přehodím pořadí requestů viz. nahoře.

<?php
$grid = new \Grid();
$this->addComponent($grid, $name);
?>

Editoval Phalanx (15. 10. 2018 20:17)

CZechBoY
Člen | 3608
+
0
-

jo počkat, ty přidáváš komponentu v createComponent :D
Ten addComponent dej do action/startup metody. Případně, pokud chceš zachovat createComponent, tak můžeš zavolat $this->getComponent(‚emailsGrid‘) v action/startup metodě a vynutíš tak její vytvoření hned při spuštění presenteru a ne pomocí líného vytvoření.

Phalanx
Člen | 310
+
0
-

@CZechBoY Kód cos poslal jako první s onAnchor mi pomohl. Pak už jsem nepotřeboval tu komponentu hned vytvářet, takže jsem ještě odstranil addComponent a vše už je krásně líné :-)

Jen mě překvapilo pořadí requestů při addComponent, ale teď už je logické.

Přidat do startup atd. – dobré k zamyšlení.

Díky za tvou ochotu