Po upgrade Nette na 2.4 se akce chová jinak a vyžaduje šablonu
- milanb
- Člen | 64
Ahoj,
udělal jsem upgrade z v 2.3 na 2.4 apliakce, kterou jsem původně nepsal.
Ve formuláři obsluhuju tlačítko pomocí signálu
editAction
:
<a href="/actions/default/165/?do=editAction&admin=0">Uložit</a>
V JavaScriptu je pak funkce editActionClick: function(event)
,
která pro aktualizaci dat používá POST:
$.post('/actions/save/' + action,...
(action
je ID
záznamu, který se má aktualizovat).
Funkce presenteru pro obsluhu akce save
je
actionSave($id)
ve svém těle pracuje s DB a na konci vytvoří
Latte objekt podle šablony ActionsList.latte
:
$latte = new Latte\Engine;
$latte->render(__CONTROL__ . '/actions/ActionsList.latte', [...
V případě úspěchu POST requestu se v JS volá
.done(my.editActionSuccess)
, a ta aktualizuje obsah fragmentu
stránky pomocí této JS funkce:
editActionSuccess: function( data )
{
$('#actions-list').html($(data).html());
Funkce v JS editActionSuccess
se tedy snaží nahradit obsah
<div id=actions-list>
tím, co vrátil POST request –
vygenerované HTML. V konzole jsme si ho nechal vypsat a fakt tam je.
Až k tomuto místu vše chápu a funguje to. Pak se ale něco v běhu
aplikace ještě dál řeší a tam mě Tracy vyhodí chybu:
Missing template 'D:\TEMP\_0repos\magnusys\app\presenters\templates\Actions\save.latte'.
Problém je asi v tom, že se pomocí toho POST zavolá akce presenteru
/actions/save/165
(ID 165 jsem dal jako příklad), asi by se to
mělo volat jinak, ne jako akce., ale nevím, jak.
Díky za každou radu, co s tím…
Editoval milanb (19. 3. 18:05)
- m.brecher
- Generous Backer | 763
@milanb
missing template …\app\presenters\templates\Actions\save.latte
Presenter se pokusí načíst defaultní šablonu akce save, což Ty nepotřebuješ.
Protože request odesíláš ajaxově, měl by se v akci presenteru ajaxově zpracovat. Tj. odeslat html snippet, který máš v __CONTROL__ . ‚/actions/ActionsList.latte‘ pomocí standardní metody Nette pro ajax sendJson(). Pokud presenter odešle request pomocí sendJson() tak potom šablonu akce už nehledá.
Jinou možností je po volání $latte->render() ukončit činnost presenteru $this->terminate(), ale to je nouzové řešení.
- Šaman
- Člen | 2635
Moc tomu nerozumím, vypadá to, že všechno obchází pohodlné nativní
funkce Nette.
Ale samotná metoda actionSave
se nic vykreslit nesnaží a pokud
tady provedeš nějaké překreslení, nebo ukončení presenteru, šablonu to
po tobě chtít nebude. K tomu dojde až PO action, když se zkouší
render.
Imho by stačilo vytvořit metodu renderSave($id)
, kde jen
nastavíš soubor s šablonou (neměl bys ji vytvářet ručně a pokud ten
soubor bude na standardním místě a správně pojmenovaný, načte se sám a
není nutná ani ta prázdná render metoda). Pokud to voláš opravdu
z presenteru.
Pokud to ale chceš zachytit a vykreslit po svém v
actionSave($id)
, mělo by to fungovat. Zkus případně po tom
render()
dát ještě řádek $this->terminate();
A uvidíš jestli se něco vykreslilo, nebo to nedohledalo ten
ActionsList.latte
.
- m.brecher
- Generous Backer | 763
@milanb
. Taky mě napadlo z toho JS nevolat action, ale opět AJAX handler
Ano, lepší by bylo použít pro komunikaci signál editAction, který tam už máš:
<a href="/actions/default/165/?do=editAction&admin=0">Uložit</a>
a potom se javascriptem přesměruje na jinou akci – z akce default na akci save:
$.post('/actions/save/' + action,... (action je ID záznamu, který se má aktualizovat).
Měl by Jsi si vytvořit handler signálu a v něm volat metodu save() modelové třídy, to by bylo lepší.
Z Nette odesílat html snippet pomocí sendJson() a akci presenteru save vůbec nepoužívat.
Poznámka k názvosloví:
action je ID záznamu
lepší je pro ID záznamu použít jméno parametru id
do=editAction
nepoužívat pro jména signálů suffix Action, handler signálu by potom byl handleEditAction(), což se může plést s akcemi presenteru, lepší by bylo použít pro signál jméno edit! a handler handleEdit()