Persistence komponent

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

Zdravim

Mam jiz delsi dobu takovy problem. Mam presenter s komponentou DataGrid (moje komponenta – je zde na foru). Tato komponenta je oznacena jako persistetni a vytvarena pomoci tovarnicky:

/**
 * @persistent(tableDG)
 */
class TabulkaPresenter extends BasePresenter {

	// ...

	protected function createComponent($name) {
		switch ($name) {
		case 'tableDG':
			$dg = new DataGrid($this, $name);
			$dg->setItemsPerPage(20);
			$dg->setUseAjax(false);
			// $ds = ...
			$dg->setDataSource($ds);
			return;
		default:
			parent::createComponent($name);
			return;
		}
	}
	// ...

}

Tento presenter ma nekoli view.

  • table – tabulka s daty a odkazy na formular pro upraveni a novy zaznam
  • form – formular pro upraveni a novy zaznam a odkaz zpet na tabulku

Odkaz vedouci na formular spravne predava persistentni komponenty, ale odkaz zpet (z formulare na tabulku) jiz nic nepredava. Parametry se proste ztrati. Co delam spatne?

DIKY

Editoval phx (20. 5. 2009 16:30)

phx
Člen | 651
+
0
-

Nikdo nevim?

Funguje to nekomu nebo ten problem maji vsichni a nikomu nevadi?

phx
Člen | 651
+
0
-

Muzete prosim nekdo zareagovat… cetl to vubec nekdo?

David Grudl
Nette Core | 8228
+
0
-

Bylo by ideální, kdybys sel dal ke stažení minimální funkční kód.

phx
Člen | 651
+
0
-

:) jdu na to…

Takze uplne nejjednoduseji: http://nette.phx.cz/bug/

Editoval phx (11. 6. 2009 10:28)

romansklenar
Člen | 655
+
0
-

Ono tu komponentu musíš někde v té akci edit vytvořit, takže aspoň:

public function actionEdit() {
	$this->getTest();
}
phx
Člen | 651
+
0
-

To mi prave prijde divny… K cemu tam potom je tedy tovarnicka?

Jde mi o toto: Mam treba vypis tabulyk (view=table) a tabulka si pamatuje razeni, stranku a tak. Dale mam pohledy new a edit. Takze vsude musim vytvaret onen DataGrid? A co kdyz kazdy radek z tabulky bude mit stranku detail (podedeny presenter) zase s moznostmi edit a new. Takze to jdou dalsi mista kde bych mel vytvaret vsechny predesle komponenty?

Osobne bych celka nejaky mechanizmus co by to za me zaridil. Kdyz uz je komponenta oznacena jako persistentni tak bych se o to uz nemel dal starat ne?

Reseni by bylo aby to but bezhlave ty parametry predalo zpet a nebo aby to projelo vsechny persistentni komponenty v linii a u kterych to obejvi neco v GET tak ty vytvorilo.

PS: omlouvam se ze reaguji tak pomalu, ale desi me zitrejsi zkouzka z Makroekonomie:(

jasir
Člen | 746
+
0
-

Ahoj, je to možná stejné jako tady. Pokud ano, zajímalo by mě jestli to bude fungovat když změníš pořadí saveGlobalState() a renderTemplate() (viz ta odkazovaná diskuze)

…Asi je to blbost, zapomeňte…

Editoval jasir (16. 6. 2009 12:45)

phx
Člen | 651
+
0
-

Nepomohlo…

Nejake dalsi reakce? Davide co si o tom myslis?

phx
Člen | 651
+
0
-

Marne jsem doufal, ze v posledni revizi se neco zmeni nic:(

Chtelo by to vyresit systemove… sice romanuv napad je funkcni, ale nesystemovy.

David Grudl
Nette Core | 8228
+
0
-

Řešením by mohlo být přídat někam sem kód

foreach (PresenterHelpers::getPersistentComponents(get_class($this)) as $name => $foo) {
	$this->getComponent($name);
}

Můžeš to zkusit?

phx
Člen | 651
+
0
-

Zda se, ze to funguje:)

Otazka zni zda je vhodne vytvaret komponentu. Zda to neni zbytecna rezie. Mozna by stacilo ony parametry proste bezhlave predat zpet. Vzdyt vsichni potomvi a ostatni view s tou komponentou nepracuji, pouze si pamatuji jeji parametry.

Panda
Člen | 569
+
0
-

Potýkal jsem se s podobným problémem – na persistentní parametry mi nereagovala komponenta v komponentě (konkrétně VisualPaginator), protože se vytvářela až při renderování mateřské komponenty.

Na konec metody Presenter::initGlobalParams() jsem si přidal cyklus, který projde „globální parametry“, vytahá z nich komponenty, ke kterým dané parametry patří a vytvoří je:

# version: Presenter.php 459 2009-07-23 09:32:18Z david@grudl.com $
--- ../nette-0.9-PHP-5.2/Nette/Application/Presenter.php
+++ lib/Nette/Application/Presenter.php
@@ -1227,6 +1227,22 @@
 		}

 		$this->loadState($selfParams);
+
+		// init the persistent components
+		foreach (array_keys($this->globalParams) as $uniqueId) {
+			$componentPath = explode(IComponent::NAME_SEPARATOR, $uniqueId);
+
+			$persistentComponents = PresenterHelpers::getPersistentComponents($this->getClass());
+			if (!isset($persistentComponents[$componentPath[0]]))
+				break;
+
+			$component = $this;
+			foreach ($componentPath as $componentName) {
+				$component = $component->getComponent($componentName, FALSE);
+				if ($component === NULL)
+					break;
+			}
+		}
 	}

phx: Tato úprava metody Presenter::saveGlobalState() můj problém také vyřešila:

<?php
	protected function saveGlobalState()
	{
		//commented: $this->globalParams = array();
		$this->globalState = $this->getGlobalState();
	}
?>

Link na Tvůj příklad už nějak ale nefunguje, můžeš to vyzkoušet i Ty? Nejsem si úplně jistý, jestli s tím nebudou nějaké problémy…

David Grudl
Nette Core | 8228
+
0
-

Snad vás potěším zprávou, že tento bug byl konečně vyřešen ;)

jasir
Člen | 746
+
0
-

David Grudl napsal(a):

Snad vás potěším zprávou, že tento bug byl konečně vyřešen ;)

:-) Rozhodně, díky. Je to stejný problém jako tady ?

David Grudl
Nette Core | 8228
+
0
-

Ano, je to to stejné. K vyřešení bylo potřeba přejít na mechanismus továrniček.

jasir
Člen | 746
+
0
-

Díky, paráda!

Panda
Člen | 569
+
0
-

David Grudl napsal(a):

Snad vás potěším zprávou, že tento bug byl konečně vyřešen ;)

Potěšíš, moc děkujeme :)

romansklenar
Člen | 655
+
0
-

Paráda!