Refresh dat v komponente, ktera jsou predavana z presenteru
- Muhahe
- Člen | 79
Zdravím, řeším ajax po odeslání formuláře, kde bych chtěl aby se mi refreshnuli data v komponentě. Formulář odesílá data do databáze(to už funguje), a snad jsem správně nastavil i invalidaci komponenty, ale ta se neobnoví. Problém může být, že data do komponenty předávám z presenteru při jejím vytváření (potřebuji volat stejnou komponentu s různými daty). Existuje na to nějaké řešení?
Vytváření komponenty v presenteru:
<?php
protected function createComponentProjectList() {
if ($this->user->isInRole('0')) {
$control = new showProjectList($this->projektyRepository->findAllProjectsByView($this->user->id), $this->ukolyRepository->findAllTasksByView($this->user->id),$this->projektyRepository);
} else {
$control = new showProjectList($this->projektyRepository->findAllProjects(), $this->ukolyRepository->findAllTasks(),$this->projektyRepository);
}
return $control;
}
?>
Zde je kód zpracovávající formulář po odeslání (kód proběhne, data jsou po refreshi v komponentě správně), ale nepovede se invalidace.
<?php
public function createNewProjectSubmitForm(Form $form) {
if(!$this->isAjax()){
$id = $this->projektyRepository->newProject($form->getValues());
$this->redirect('Projects:projectDetail', $id);
}else{
$id = $this->projektyRepository->newProject($form->getValues());
$this->getComponent('projectList')->invalidateControl();
}
}
?>
- Muhahe
- Člen | 79
Nějak jsem nepochopil co jsi myslel tím předat logiku do komponenty, ale zkusím popsat moji myšlenku.
Komponenta reprezentuje tabulku obsahující údaje z databáze. Pomocí jquery UI dialog vykresluji formulář pro přidání údajů do databáze přez AJAX. Po přídání bych rád, aby se komponenta překreslila s aktuálními udaji.
Komponentu vykresluji na různých místech a data která se mají vykreslit určuji v presenteru. Ten sáhne do modelu, vybere data a předá je parametrem komponentě. A zde si právě nejsem jist, jestli při pokusu o invalidaci a překreslení komponenty se mi i znovu přečtou data z databáze.
Felix napsal(a):
Mozna bych tu logiku presunul do komponenty a pak v sablone mel treba,
{control projectList, id => $id}
Zkus trochu vic popsat jak ji chces pouzit.
- Muhahe
- Člen | 79
Jeste me napadlo jestli mam ubec spravnou myslenku a jestli je to mozne.
Prezenterem na dane strance vykresluji pouze komponentu (nazveme ji A) a komponentu na vykresleni formulare pro pridani projektu (nazveme ji B).
latte sablona stranky
{block content}
<div>
<h1>Projects</h1>
{control projectList}
<div id="newProjectFormContainer">
{control newProjectForm}
</div>
<div id="newTaskFormContainer">
{control newTaskForm}
</div>
</div>
{/block}
Komponenta formulare je skryta a zobrazuje se az po kliknuti tlacitka pomocí jquery dialog.
Po vyplneni a odeslani formulare je volana metoda presenteru createNewProjectSubmitForm, ktera by mela pridat projekt do databáze a invalidovat komponentu A (překreslit a zobrazit přidaný projekt). Metoda createNewProjectSubmitForm se nachazi v presenteru.
<?php
public function createNewProjectSubmitForm(Form $form) {
if (!$this->isAjax()) {
$id = $this->projektyRepository->newProject($form->getValues());
$this->redirect('Projects:projectDetail', $id);
} else {
$id = $this->projektyRepository->newProject($form->getValues());
$this->invalidateControl('projectList');
$this->getComponent('projectList')->invalidateControl();
}
}
?>
Projekt se do databaze prida spravne, avsak nejsem schopen zprovoznit invalidaci komponenty.
Komponenta A je volana v presenteru a jsou ji predany data, ktera se maji zobrazit.
Zkousel jsem i funkcnost samotne invalidace tak, ze v komponente vypisuji aktualni cas kdy byla komponenta vykreselena (v pripade ze by se nepredali data), ale cas se neaktualizuje. Z cehoz odvozuji ze ani komponenta se neinvaliduje.
Je ubec mozne aby tento princip fungoval? Pokud by byl nekdo ochotny pomoci, velice rad poskytnu pripadne dodatecne info, ale nenapada me co vice dal bych mel uvest.
Za jakoukoli pomoc budu velice rad.
Editoval Muhahe (26. 12. 2013 11:10)
- Jan Suchánek
- Člen | 404
@Muhehe: Predat do komponenty je mysleno tak, aby komponenta dostala model a parametry, model prez neon. Celou logiku delegovat na komponentu a tim odlehcit spagety v presenteru?
- Muhahe
- Člen | 79
jenicek napsal(a):
@Muhehe: Predat do komponenty je mysleno tak, aby komponenta dostala model a parametry, model prez neon. Celou logiku delegovat na komponentu a tim odlehcit spagety v presenteru?
Momentalne vytvarim komponentu A takto
<?php
protected function createComponentProjectList() {
if ($this->user->isInRole('0')) {
$control = new showProjectList($this->projektyRepository->findAllProjectsByView($this->user->id), $this->ukolyRepository->findAllTasksByView($this->user->id), $this->projektyRepository);
} else {
$control = new showProjectList($this->projektyRepository->findAllProjects(), $this->ukolyRepository->findAllTasks(), $this->projektyRepository);
}
return $control;
}
?>
Mam to z toho duvodu, ze konponentu potrebuji volat z vice mist s ruznymi daty.
Pokud dobre chapu tvuj navrh, mel bych logiku, ktera urcuje jaka data budou zobrazena presunout do komponenty?
A nebo predavat referenci na model primo komponente?
<?php
...
$control = new showProjectList("predat model", "parametr vyberu")
...
?>
Nebo jeste treti moznost me napada z toho co sem tu cetl, tak zaregistrovat model komponente v souboru .neon?
Bohuzel se ptam jako prumerny primat, ale jsem z toho trochu zmaten. Jeste me napada, neni zde na to v ukazkach, nebo planette nejaka ukazka? Snazil jsem se neco najit ale neuspesne tak jestli mi neco neuniklo.
Pokud by slo o druhou moznost, porad me zarazi ze se neinvaliduje alespon ten cas.
- Jan Suchánek
- Člen | 404
@Muhahe: Mit komponentu v configu a tam ji predat modely a na parametry setry v presentreru?
- Šaman
- Člen | 2659
Vytvořil jsem Gist s ukázkou komponenty, která si injectuje závislosti pomocí autowiringu přímo v configu.
Ukázka by se dala ještě zjednodušit, tohle jsem vykopíroval z jednoho
ukázkového projektu. Idea je taková, že kromě komponenty si vytvoříš
tovární třídu (servisu), která dostane všechny závislosti v configu jako
jakákoliv jiná servisa a ty si ji injectneš do presenteru a pomocí ní
vytváříš konkrétní instance dané komponenty.
Ty traity jsou jenom kvůli zjednodušenému injectování, s problematikou
továrny nijak nesouvisí.
Jestli ti tohle bude jasné, tak si ještě zkus vyhledat něco o generovaných továrničkách – aplikace se ti pak ještě maličko zmenší, protože část kódu si Nette vygeneruje samo. V Nette 2.1@dev pro to byla sekce factories, dnes se to prý změnilo, tak ukázku neposílám. V principu to je však totéž, jen není potřeba psát celou tovární třídu, ale jen její rozhraní.
Dodatek: @Jenicek: Není dobré vytvářet přímo komponentu v configu, protože komponent můžeš mít na stránce několik a v configu můžeš vytvářet jen servisy (tedy konkrétní instance, které se předávají v celé aplikaci). Proto si v configu vytvoříš jen továrnu (služba, stále jen jedna), která na požádání vytvoří libovolný počet konkrétních komponent.
Editoval Šaman (26. 12. 2013 13:46)
- Jan Suchánek
- Člen | 404
@Muhahe: Napsal bych priklad, ale pisu z mobilu a neni to moc user friendly.
- Muhahe
- Člen | 79
Jeste me napadlo, ciste z edukativnich duvodu, ty mnou vyse uvedene zpusoby
nejsou mozne?
Pripadne proc? Protoze komponenta je s parametrem?
Dale jsem v ukazkach nasel navody na jednoduchou invalidaci, ktera se pouzivala
tak jak jsem to zkousel.
Precetl jsem snad kompletni sekci dokumentace, ale zustava mi dost otazek. Nerad
bych prudil, jen mne to porad vrta hlavou.
- Jan Suchánek
- Člen | 404
@Muhahe: Šamanovo řešení je čistší, napr me vadilo dvakrat new toho sameho konkretne showProjectList, ale pokud je to pro tebe ok?
- Muhahe
- Člen | 79
jenicek napsal(a):
@Muhahe: Šamanovo řešení je čistší, napr me vadilo dvakrat new toho sameho konkretne showProjectList, ale pokud je to pro tebe ok?
To samozrejme mas pravdu, to dvakrat new nebylo moc uzasny, ale momentalne mi jde spis o vysledny princip, proc ta invalidace nefungovala. Jde mi spise o celkovy vysledek nez o uhlazenost kodu. Te jsem se chtel venovat pote az bude funkcnost ± hotova.
Postupoval jsem myslenkove asi tak: vedel jsem co chci → nasel jsem jak to udelat → zkusil jsem to naprasit, abych overil jestli to funguje spravne (zde jsem se zasekl) → dal bych do pucu kod
A prave k tomu poslednimu bodu uz jsem se nedostal :/
Editoval Muhahe (26. 12. 2013 17:33)
- Muhahe
- Člen | 79
jenicek napsal(a):
@Muhahe: neni invalidateControl depricated? Co ti vraci firebug pri ajaxu?
Problem je, ze ani firebug, ani chrome, ani IE konzole nevyhodi zadnou chybu. Pozadavek ajaxu je 200 OK, data se pridaji a kdyz refreshnu stranku tak je vse tak jak ma byt. Jedine co neprobehne, tak je prave ta invalidace komponenty, ktera by to refreshnuti mela zaridit (pokud jsem vse spravne pochopil).
Jestli je deprecated, tak to nevim nikde jsem to nenasel.
Kdybych tam mel chybove hlasky tak bych s tim neotravoval, ale tohleto me prave dostava do kouta. Dokonce nette log je taky prazdnej.
Proste z nejakeho duvodu invalidace neprobehne a nejsem schopen dat dohromady proc.
Editoval Muhahe (26. 12. 2013 20:23)
- Muhahe
- Člen | 79
jenicek napsal(a):
http://bit.ly/1c9a8ZE zkus mrknout
Koukam na to, ale jedna se teprve o testovaci verzi ne? Pouzivam 2.0.8 a predpokladal jsem ze by tam melo ± vse fungovat.
Zkusim jsem preskocit na novou verzi nette a redrawControl() je stejny problem. Polozka se prida, ale komponenta se neprekresli chybova hlaska neni ani v chrome, firebugu, IE konzoli, nette logs.
Editoval Muhahe (26. 12. 2013 21:37)
- jiri.pudil
- Nette Blogger | 1029
Dvě otázky:
- Ve Firebugu i v Chrome Dev Tools se můžeš podívat na obsah, který ti ten ajaxový požadavek vrátil. Je v něm to, co očekáváš (tzn. položka „snippets“ obsahující aktualizovaná data)?
- Co vlastně používáš pro ajaxizaci na straně klienta? nette.ajax.js?
- Muhahe
- Člen | 79
jiri.pudil napsal(a):
Dvě otázky:
- Ve Firebugu i v Chrome Dev Tools se můžeš podívat na obsah, který ti ten ajaxový požadavek vrátil. Je v něm to, co očekáváš (tzn. položka „snippets“ obsahující aktualizovaná data)?
- Co vlastně používáš pro ajaxizaci na straně klienta? nette.ajax.js?
Ve firebugu->Konzole->All->odezva vraci prazdne pole state (nebo JSON).
Na strane klienta pouzivam nette.ajax.js verze 1.2.2 stazene primo ze stranek Nette.
A prave co se tyce bodu 1) tak tam prave tusim ze bude problem, ze se invalidace/prekresleni neprovede ale nedokazu prijit nato proc. Snazil jsem se vse jed dle navodu.
Editoval Muhahe (26. 12. 2013 22:30)
- Jan Suchánek
- Člen | 404
A mas spravne vse obalene snipetama v latte? A kdyz se ti vraci payload co konkretne vrati? Nic?
- Jan Suchánek
- Člen | 404
@Šaman: komponentu vytvarim pomoci interface, lze jednim interfacem vyrabet vic ruznych komponent nebo jen vic stejnych komponent. Myslim posledni plati ne?
- Šaman
- Člen | 2659
@jenicek: Pošli nějakou ukázku, nevím co myslíš tím interface. JEstli generované továrny, tak to je v pohodě. Ale tím v kontejneru nevytváříš tu komponentu, ale tovární třídu (generovanou), která pak v konkrétních továrničkách presenteru (metoda createComponentXxx) vytváří konkrétní instance.
- Jan Suchánek
- Člen | 404
@Šaman: tak to provadime stejne. V createComponentXxx je napr. $control = $this->example->create() a dosetuju a vratim jako vysledek. Jen sem se ptal, zda jednou takovou tovarnou mohu vracet i jinou komponentu nebo je to vazane na jedinou?
- Šaman
- Člen | 2659
Jestli si nepíšeš vlastní tovární třídu (jak to mám v ukázce) a
využíváš generované továrny, tak při každém zavolání metody
create()
dostaneš novou unikátní instanci komponenty (ta metoda
create v sobě obsahuje vytváření pomocí new
).
Pokud si píšeš vlastní, tak záleží na tom, jak si to napíšeš. Ale od metody create bych vždy očekával vytvoření nové instance.
Takže odpověď je, že můžeš vytvářet kolik chceš nezávislých komponent.
Editoval Šaman (27. 12. 2013 10:30)
- Muhahe
- Člen | 79
jenicek napsal(a):
A mas spravne vse obalene snipetama v latte? A kdyz se ti vraci payload co konkretne vrati? Nic?
Hmm tak ted si nejsem jistej jeslti jsem postupoval spravne, ale mel sem zato ze pokud chci invalidovat komponentu, pak nemusi byt obalena snipettem, nekde jsem to cetl pokusim se znovu najit.
A ted asi trochu blba otazka, ale payload neni v firebugu zalozka odpoved? Pripadne kde payload zistim?
- Jan Suchánek
- Člen | 404
@Muhahe: Ze by nemela byt obalena snipetem to si nemyslim. Kde si na to prisel?