Něco málo o Ajaxu

Rudolf Svátek 2016-07-21 10:41

Jako vždy, celou aplikaci si můžeš stáhnout: kapitola12.zip

Ajax je fajn. Hlavně pro uživatele. Celkem zrychluje odezvu stránek, protože nemusí po každé akci obnovovat celou stránku v prohlížeči. Prostě se něco provede a pokud se má na stránce něco změnit, překreslí se jen to, co je zapotřebí. Kupříkladu při přesouvání stránek, mazání novinek, nebo nastavení stránky jako aktivní, tam všude najde Ajax uplatnění. Totiž proč by se měla načítat znovu celá stránka, když se jen jedné stránce změnil jeden údaj?

Nette ti dost usnadňuje práci, protože stačí jen nahrát pár JS knihoven, doplnit třídu "ajax" do HTML kódu k těm elementům, které chceš zajaxovat a obalit je takzvanými snippety. V metodě, která se stará např. o zpracování odeslaného formuláře, nebo prostě u čehokoli, co normálně končí přesměrováním a znovunačtením stránky, se jen zeptáš, jestli je to ajaxový požadavek. Pokud ano, překreslíš jen příslušnou část stránky. Pokud ne, normálně přesměruješ a obnovíš celou stránku, jako by ajax neexistoval.

Pokud s Nette začínáš, nebo s Ajaxem v Nette, doporučuji postudovat: https://doc.nette.org/cs/2.4/ajax.

Javascriptové knihovny

Ať už jsi na to přišel, nebo ne, tak v těch archivech, co ti nabízím ke stažení, už jsou knihovny pro práci s Ajaxem. Ostatní potřebné knihovny se načítají v hlavní šabloně @layout.latte. Nic si tedy nemusíš stahovat, protože všechno už máš, pokud sis stáhnul nějaký ten zip s aplikací.

Když si otevřeš soubor app\AdminModule\presenters\templates@layout.latte, uvidíš na prvním řádku:

{var ajax = $presenter->getParameter('ajax') == 'on'}

Tím se naplní javascriptová proměnná "ajax", která bude nastavena na 1, pokud presenter pošle do šablony proměnnou "ajax" s hodnotou "on". Jinak se javascriptová proměnná nastaví na 0. Tím rozlišuji, zda chci, nebo nechci Ajax používat.

V šabloně taky vidíš řádky podobné tomuto:

<script n:if="$ajax" src="{$basePath}/js/grido.nette.ajax.js"></script>

To n:if právě testuje proměnnou a pokud je nastavena, provede se blok. V příkladu výše je to includování souboru grido.nette.ajax.js. pokud proměnná nastavena není, ani nepotřebuji Ajaxové knihovny.

BasePresenter

Ajax se spouští tehdy, pokud je v presenteru řešeno, že $ajax = 'on'. Na to se bezvadně hodí BasePresenter. Doplníme 2 řádky:

	/** @var string @persistent */
	public $ajax = 'on';

Nastavili jsme parametr $ajax jako persistentní. To je dobrá vychytávka Nette. Bylo by samozřejmě dost otravné posílat s každou stránkou v URL parametr &ajax=on. Pokud ale nastavíme v presenteru nějaký parametr jako persistentní, bude se to chovat, jako by se parametr s danou hodnotou v URL poslal.

Jakmile ty 2 řádky doplníš, začnou se v šabloně načítat ajaxové knihovny.

Kdybys to chtěl u nějakého konkrétního presenteru změnit, můžeš přímo v něm ten parametr přepsat na:

	/** @var string @persistent */
	public $ajax = 'off';

Nebo prostě místo 'on' dej cokoli jiného.

Snippety

Snippet je makro v latte šabloně. Obaluje se jím něco, co chceš vykreslit. Zbytek stránky pak zůstává nevykreslený. Proto je třeba v šabloně pro výpis stránek, novinek apod. uvedeno toto:

	{snippet grid}
		{control grid}
	{/snippet}

{control grid} způsobí výpis záznamů. V něm je třeba možné nastavit novinku či stránku jako aktivní. Když klikneš na dané tlačítko, zavolá se fuknce pro danou událost. Třeba u novinek je to:

	/**
	 * @param $id
	 */
	public function handleActive($id) {
		$news = $this->newsRepository->get($id);
		$news->active(!$news->active());
		$this->newsRepository->save($news);
		if (!$this->isAjax())
			$this->redirect('default');
		$this->redrawControl();
	}

Všimni si řádku 8. Testuje se tam, jestli byl požadavek odeslán ajaxově. Pokud ne, provede se přesměrování celé stránky. Jestliže ale ano, pak se překreslí jen snippety. Kdybys to chtěl ještě upřesnit, můžeš uvést i název snippetu a pak by to volání pro překreslení vypadalo takto:

$this->redrawControl('grid');

Třída "ajax"

Ještě jedna podmínka musí být splněna. Presenter musí vědět, že požadavek má být ajaxový. Někdy vážně chceme pomocí odkazu načíst celou stránku. Například zase u novinek - ajaxově chci provést smazání novinky, ale editaci ne, jelikož u mazání nepotřebuji zobrazovat nějaký formulář, zatímco u editace musím. Proto je v gridu toto:

		$grid->addActionEvent('delete', '')
			->setCustomRender(function ($item) {
				$i = Html::el('i', ['class' => 'fa fa-trash']);
				$el = Html::el('a', ['class' => 'btn btn-default btn-xs btn-mini ajax'])
					->href($this->presenter->link("delete!", $item->id))
					->setHtml($i);
				return $el;
			});
	 		$grid->addActionHref('edit', '')
			->setIcon('pencil');

Možná bude srozumitelnější ukázat už vygenerovaný HTML kód:

<a href="/admin/news/default/1?do=delete" class="btn btn-default btn-xs btn-mini ajax">
    <i class="fa fa-trash"></i>
</a>

Prostě k vygenerovanému tlačítku přidám třídu "ajax". Hotovo. O zbytek se postará Nette.

Ajaxové formuláře

Také formulář lze odeslat ajaxově. Opět je nutné mu dát třídu 'ajax'. V komponentě jen stačí přidat řádek:

$form->getElementPrototype()->class('ajax');

Nebo pokud vykresluješ v šabloně formulář ručně, prostě tam tu třídu doplníš. V administraci tak, jak ji máme teď, zřejmě nenajdeme moc příležitostí pro Ajaxové zpracování formuláře. Ale třeba při přidávání komentářů k článkům to můžeme budoucím uživatelům nabídnout. Jakmile přidají komentář, prostě se ukáže, ale stránka se nebude přenačítat celá.

Tak dnes to bylo krátké, ale snad zajímavé. A jako vždy, celou aplikaci si můžeš stáhnout: kapitola12.zip.

Redakční systém RS::RS Předchozí kapitola

Administrace novinek

Redakční systém RS::RS Celý seriál

Vývoj redakčního systému v PHP

Redakční systém RS::RS Následující kapitola

Nastavení aplikace

Komentáře (0)

Přidej svůj komentář

O mně

Jmenuji se Rudolf Svátek. Jsem lektor výpočetní techniky a PHP programátor. Stavím firemní stránky a eshopy. Aby se mi to dělalo pohodlně, vytvořil jsem redakční systém RS::RS, který ti tu nabízím k použití.

Rychlý kontakt na mně

  • Rudolf Svátek
  • Telefon:
    +420 777 828 353
  • Email:
  • Adresa:
    Josefa Hory 1097/5
    736 01 Havířov
    ČR



Tyto stránky používají Cookies. Používáním stránek s tím souhlasíte Další informace