Ajaxová aplikace → Přechod na jiný presenter a akci pomocí AJAX

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

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?

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Můžeš si to dát do beforeRender, pak to nemusíš kopírovat všady.

bojovyletoun
Člen | 667
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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ů:

  1. Ajaxem se odešle formulář
  2. 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.
  3. Podle persistentních parametrů se provede, co je potřeba (jejich účel).
  4. Provede se invalidace potřebných snippetů.
  5. Do payloadu se uloží např. $this->payload->url = $this->link('this');.
  6. A tato se v JS zpracování použije do pushState.