Ajaxová aplikace → Přechod na jiný presenter a akci pomocí AJAX
- MartinitCZ
- Člen | 580
Chtěl jsem se zeptat, jestli se nedá nějak usnadnit zápis a jak to děláte vy?
V rámci sebezdokonalení se učim AJAX a narazil jsem na jednu věc.
V případě, že chci aplikaci mít celou ajaxovou, tak musím do každá akce koopírovat tento kod:?
if ($this->isAjax()) {
$this->invalidateControl('flash');
$this->invalidateControl('content');
//.....
//.....
} else {
$this->redirect('this');
}
Nedá se to dělat jednodušeji?
- bojovyletoun
- Člen | 667
kdysi jsem měl takový helper
<?php
use Nette\Application\UI\Control;
class AjaxRefresh
{
/**
* @param string|array snippet names
* @param string link destination in format "[[module:]presenter:]view" or "signal!"
* @param array|mixed
* @return void
*/
public static function refresh($object, $snippets = NULL, $destination = 'this', $args = array())
{
if ($object->getPresenter()->isAjax()) {
if ($snippets) {
foreach ((array) $snippets as $snippet) {
$object->invalidateControl($snippet);
}
} else
$object->invalidateControl();
} elseif ($destination)
$object->redirect($destination, $args);
}
static function register()
{
Control::extensionMethod("refresh", array(__CLASS__, "refresh"));
}
}
- MartinitCZ
- Člen | 580
vojtech.dobes: Díky za odpověd tohle mne nenapadlo.
bojovyletoun: Díky, kouknu na to.
Ještě bych měl dotaz ohledně odeslání formuláře pomocí AJAX.
Mám formulář, který je složen z checkboxů.
foreach($this->model->names->get() as $default) {
$this->addCheckbox($default->slug, Strings::firstUpper($default->name))
->controlPrototype->class("name");
}
// Zpracování
foreach($values as $slug => $value) {
if($value === TRUE) {
$this->names[] = $slug;
}
}
if ($this->presenter->isAjax()) {
$this->presenter->invalidateControl("flash");
$this->presenter->invalidateControl("content");
} else {
$this->presenter->redirect("Homepage:default", array("name" => (array) $this->names));
}
V případě, že chci využít AJAX, tak se nevytvoří URL (viz poslední řádka), tim pádem neví, co se má dít. V konzoli vše proběhne OK, ale díky tomu, že v URL nemám dané parametry, tak se nic nezmění. Řešil jste někdo něco podobného (jak přidat parametry bez redirectu)?
PS vojtech.dobes: Využiji příležitosti a rád bych ti poděkoval za tvou přednášku z Poslední soboty. ;)
Editoval martinit (1. 6. 2012 14:30)
- Vojtěch Dobeš
- Gold Partner | 1316
Můžeš provést $this->forward()
, to je jak
redirect()
(má i stejné parametry), ale provede se v rámci
jednoho HTTP požadavku, tzn. pro prohlížeč a Ajaxový požadavek to bude
praště jak uhoď.
PS: Rádo se stalo :).
Editoval vojtech.dobes (1. 6. 2012 14:56)
- MartinitCZ
- Člen | 580
O tomto způsobu jsem nevěděl. Díky.
Akorát to tedy bohužel nepůjde tak, jak sem si naivně myslel.
Ale napadlo mne. Pokud formulář předělám tak, že po zakliknutí se ajaxem odešle. Jen musim vymyslet jak na to?
Představuji si to úplně stejně jako je to zde (zaškrtávání
značek):
http://www.alza.cz/…18852056.htm
A poté vymyslet funkční routu:
https://forum.nette.org/…scalar-error#…
Editoval martinit (2. 6. 2012 13:54)
- Vojtěch Dobeš
- Gold Partner | 1316
Formulář zajaxuješ nejsnáze pomocí $.nette.ajax
:). Pokud chceš provést Ajaxový požadavek hned po kliknutí třeba na
checkbox, tak se to nejsnáze udělá následovně:
$('input[type=checkbox]').change(function () {
$(this).closest('form').submit();
});
To vyvolá odeslání formuláře, a pokud je ten formulář zajaxován (například pomocí výše uvedeného skriptu), odešle se Ajaxově.
Akorát to tedy bohužel nepůjde tak, jak sem si naivně myslel.
Co máš tímto na mysli?
Editoval vojtech.dobes (2. 6. 2012 14:39)
- MartinitCZ
- Člen | 580
vojtech.dobes napsal(a):
Akorát to tedy bohužel nepůjde tak, jak sem si naivně myslel.
Co máš tímto na mysli?
Bude formulář, v kterém zaškrtnu nějaká políčka. Zpracuje se to, do URL přidá dané parametry, dle zpracování formuláře a refrešně (snippet) to content.
Úplně stejně, jako je na to na alza.cz. Zašktrneš, ajaxem se to odešle a daný parametr se přidá do URL.
- Vojtěch Dobeš
- Gold Partner | 1316
Rozumím, tak to jsem se trefil :) Ten update URL se dělá pomocí
history.pushState
. Jde to udělat třeba pomocí persistentních
parametrů:
- Ajaxem se odešle formulář
- Ve zpracování formuláře se provede forward na desired presenter:action, včetně nastavení persistentních parametrů podle toho, co přišlo ve formuláři.
- Podle persistentních parametrů se provede, co je potřeba (jejich účel).
- Provede se invalidace potřebných snippetů.
- Do payloadu se uloží např.
$this->payload->url = $this->link('this');
. - A tato se v JS zpracování použije do
pushState
.