Jak na AJAXové odkazy v menu
- Freestyler
- Člen | 50
Ahoj,
potřebuji, abych nějakým způsobem navázal AJAX na odkazy v menu. Tzn.
Když kliknu třeba na odkaz Hlavní stránka, tak aby se reloadnul jenom obsah
a ne třeba menu a další prvky webu.
@layout.latte
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="robots" content="{$robots}" n:ifset="$robots">
<script src="../js/netteForms.js"></script>
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/admin.css">
<link rel="stylesheet" media="print" href="{$basePath}/css/print.css">
{block head}{/block}
</head>
<body>
<script> document.documentElement.className+=' js' </script>
<br />
<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
{if $user->loggedIn}
<div class="logout">
<a n:href="logout!">Odhlásit se ... </a>
</div>
<div class="menu" >
<ul class="level-1">
<li class="level-1"><a n:href="Homepage:">Hlavní stránka</a>
</li>
<li class="level-1"><a href="odkaz">Správa článků</a>
<ul class="level-2">
<li class="level-2"><a n:href="Articles:">Přidat článek</a></li>
<li class="level-2"><a href="odkaz">Přidat kategorii</a></li>
<li class="level-2"><a href="odkaz">Zobrazit článek</a></li>
</ul>
</li>
<li class="level-1"><a href="odkaz">Nastavení</a>
</li>
</ul>
</div>
{/if}
<div class="content">
{include content}
</div>
{block scripts}
<script src="{$basePath}/js/jquery.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
</body>
</html>
Kupříkladu bych rád, aby když kliknu na "Přidat článek, tak se reloadnul jen určitý <div>
Můžete sem prosím někdo hodit příklad použití snippetu v jednoduchém menu? Nic moc jsem nenašel. Díky.
Editoval Freestyler (23. 6. 2014 20:17)
- Томас
- Člen | 85
Buď zdráv,
v první řadě: Proč to tak chceš? Dejme tomu, že to takhle má nějaký
web, kam chodíš. Adresa je „www.neco.cz“. Klikneš si do menu na
„kontaktujte nás“, a jsou tam nějaký super informace a chceš to někomu
přeposlat. Jak? link je stále „www.neco.cz“ i když je obsah jinej…
vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím
obeznámen :P)
Každopádně pokud k tomu máš nějaký rozumný důvod tak to jde úplně jednoduše:
1. stáhní https://componette.org/search/?… a naincluduj si ho do layoutu
<script src="{$basePath}/js/nette-ajax-js.js"></script>
// až po jquery! -> potom už jen zavoláš metodu init
$(function () {
$.nette.init();
});
teď si to co chceš přes ajax refreshovat obalíš do nějakýho snippetu např:
<div class="menu">
<a n:href="Page:show 1" class="moje_class_na_sexy_linky ajax">kontaktujte nás</a>
<a n:href="Page:show 2" class="moje_class_na_sexy_linky ajax">něco zajímavýho</a>
// v class musí být ajax!
</div>
<div class="page">
{snippet page}
{include content}
{/snippet}
</div>
no, a máme skoro vyhráno, teď už jenom v přesenteru dát vědět, že
se bude jednat o ajax.
Dejme tomu že máš metodu nějak takto?
// PagePresenter.php
public function renderShow($pageId)
{
$this->template->page = $this->database->table('moje_sexy_clanky')->get($pageId);
if($this->isAjax()){
// jestli se jedná o ajax překresli snippet page
$this->redrawControl('page');
}else{
// pokud to ajax z nějakýho důvodu není tak není
// tak sem můžeš dát přesměrování (tady asi nic leda by to byla handle)
// $this->redirect('this');
}
}
Teď po kliknutí na link v menu se ti pomocí ajaxu překreslí ten snippet page a máme hotovo. Snad jsem na nic nezapoměl přeci jen jsem ještě nespal! :'(
Mimochodem : netteForms.js includuješ 2× → používej $basePath
Editoval Томас (24. 6. 2014 9:15)
- jiri.pudil
- Nette Blogger | 1032
link je stále „www.neco.cz“ i když je obsah jinej… vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím obeznámen
Jde to obejít pomocí History API, podpora je ve všech moderních prohlížečích a IE 10+. Vojta Dobeš na to má i rozšíření pro nette.ajax.js
- mirimCZ
- Člen | 24
Problém se SEO už je dávno vyřešený, ale vyžaduje to „trochu“ jinej level přístupu k aplikaci. Nemluvě o tom, že nette způsob tvorby SPA prvků by seo nijak narušovat neměl (v praxi jsem to nepoužil nikdy, SPA dělám jen backend a ještě k tomu na angularu), vzhledem k tomu, že ta aplikace by měla poslat celou stránku, když isAjax() spadne do false – nebo aspoň tak bych to teda programoval.
https://developers.google.com/…tml-snapshot
http://stackoverflow.com/…applications
Editoval mirimCZ (24. 6. 2014 14:54)
- Freestyler
- Člen | 50
Díky, díky. Hlavní myšlenka byla v tom, že nechci reloadovat celou stránku, když třeba menu, grafika a další prvky jsou pořád stejný a mění se prakticky jen jeden <div> a to ten se contentem a vypsanýma datama z db (momentálně řeším backend aplikace, na frontend dojde taky brzy).
A pro to je Ajax jako stvořenej ne? Nebo jak to řešíte vy? Reloadujete všechno? Budu rád za jakoukoliv radu, přece jen s nette teprve začínám a třeba mi něco uteklo.
P.S. Ještě trochu konkrétnosti:
Administrace se skládá z menu, kde se položky nemění, odkazu na odhlášení, ten se taky nemění a je pořád stejnej, grafika je naprosto stejná a uprostřed je <div> do kterýho se všechno vypisuje, ten jedinej chci při kliknutí na určitou položku v menu měnit. Jdu na to správně?
Díky.
EDIT: teď mi došlo, že to fakt není SEO, je to hodně proti proudu … (musel jsem si dát kafe aby mi to začal myslet :))
Editoval Freestyler (24. 6. 2014 19:58)
- Томас
- Člen | 85
Pokud řešíš administraci, tak si to klidně přes ajax udělej takhle. Do přední části aplikace bych to ale necpal.
BTW: Nejde mi na mozek proč ti vadí reloadovat o 20 řádků navíc, které jsou natvrdo napsané v kódu? Opravdu si myslíš, že bude nějaký rozdíl v rychlosti načítání, kor když menu atd mají dohromady 10 řádků? (neřeknu kdyby to menu mělo 150 odkazů a tahal si to z DB nebo něco trošičku časově náročnějšího, co není třeba pořád reloadovat) :-D
- Томас
- Člen | 85
jiri.pudil napsal(a):
link je stále „www.neco.cz“ i když je obsah jinej… vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím obeznámen
Jde to obejít pomocí History API, podpora je ve všech moderních prohlížečích a IE 10+. Vojta Dobeš na to má i rozšíření pro nette.ajax.js
dík, mrknu na to, mohlo by se hodit :)
- mirimCZ
- Člen | 24
Томас napsal(a):
Pokud řešíš administraci, tak si to klidně přes ajax udělej takhle. Do přední části aplikace bych to ale necpal.
BTW: Nejde mi na mozek proč ti vadí reloadovat o 20 řádků navíc, které jsou natvrdo napsané v kódu? Opravdu si myslíš, že bude nějaký rozdíl v rychlosti načítání, kor když menu atd mají dohromady 10 řádků? (neřeknu kdyby to menu mělo 150 odkazů a tahal si to z DB nebo něco trošičku časově náročnějšího, co není třeba pořád reloadovat) :-D
Nejde o deset řádků navíc, jde o to, že když klikneš na odkaz a reloaduje se ti celá stránka, posílají se znova veškeré requesty na css, javascript, obrázky a jak všichni určitě víme, právě přehršel HTTP požadavků obvykle brzdí stránky nejvíc. Pokud použiješ ajax, pošle se request jeden – ostatní už tam je a není nutné to tedy načítat znova.
Těžká datová logika z databáze by stejně měla být nacachovana – v příadě menu by bylo ideální, kdyby se nacachovalo rovnou i vyrenderované HTML menu, takže o to ani tak nejde…
Freestyler napsal(a):
A pro to je Ajax jako stvořenej ne? Nebo jak to řešíte vy? Reloadujete všechno? Budu rád za jakoukoliv radu, přece jen s nette teprve začínám a třeba mi něco uteklo.
Osobně používám AngularJS. Celej „content block“ zatím neposílám – ikdyž se na to chystám v blízké době. Momentálně používám jen asynchronní komponenty – mám asynchronní grid a formuláře. Grid normálně leží ve stránce jako by ležel ikdyž ho renderuje phpko, formuláře se otevírají do modálního okna. Do gridu ze strany php putuje čistý JSON, akce s formulářemi posílají normálně html.
Tohle řešení furt nevyužívá plného SPA potenciálu Angularu – ten umí i routování, templatování, atd
https://docs.angularjs.org/…ctive/ngView
Jinak dobře udělané SPA by phpko mělo vracet víceméně jen čistě JSON data. Templatování by pak řešil frontendovej js framework (třeba již zmíněný angular, nebo ember a podobné).
Editoval mirimCZ (25. 6. 2014 11:43)
- Freestyler
- Člen | 50
Přesně to jsem myslel, nechci reloadovat všechno, když už jsem to jednou udělal a není potřeba to dělat znova.
Tvoje řešení se mi líbí, ale bohužel zatím přesahuje moje programátorské dovednosti. Holt si zatím vystačím s tím co umím :).
Každopádně díky za rady a nápady.
- Čamo
- Člen | 798
mirimCZ:
SPA,Angula,JSON,Asynchronný javascript, Nette cache… ale to, že prehliadače
si obrázky, a javascripty cachujú, takže žiadne přehršle http requestou sa
neposielajú to nevieš. Nehovoriac o tom aký je ten kód potom prehľadný,
keď do neho narveš všetko možné aj nemožné. Toto ja nepochopím…
Editoval Čamo (28. 6. 2014 13:54)