Nefunguje Simple ajax example
- aum
- Člen | 12
Zdravím a prosím o radu.
Zkusil jsem příklad Simple ajax example (https://doc.nette.org/…ication/ajax).
Pomocí Composeru jsem vytvořil nový Sandbox-projekt, do www/js doplnil
nette.ajax.js z GitHub, přidal <script
src=„{$basePath}/js/nette.ajax.js“></script> do
@layout.latte a inicializaci do main.js.
Upravil HomepagePresenter.php a default.latte podle návodu.
Po clicku na „Change variable!“ se „default value“ změní na „changed
value via ajax“, ale ne prostřednictvím ajaxu. Zavolá se
handleChangeVariable(), ale podmínka if ($this->isAjax()) je FALSE.
Co může být špatně a jak to hledat?
Předem díky.
- aum
- Člen | 12
Zjistil jsem, že to souvisí se šablonami. V @layout.latte mám:
{**
* @param string $basePath web base path
* @param array $flashes flash messages
*}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Sandbox</title>
<link rel="stylesheet" href="{$basePath}/css/style.css">
<meta name="viewport" content="width=device-width">
{block head}{/block}
</head>
<body>
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
{include content}
{block scripts}
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
</body>
</html>
Pokud je v default.latte jen:
<div>
{snippet ajaxChange}
{$anyVariable}
{/snippet}
<a n:href="changeVariable!" class="ajax">Change variable!</a>
</div>
vůbec neproběhne {block scripts} z @layout.latte.
Pokud default.latte upravím:
{block content}
<div>
{snippet ajaxChange}
{$anyVariable}
{/snippet}
<a n:href="changeVariable!" class="ajax">Change variable!</a>
</div>
{/block}
{block scripts}
{include parent}
{/block}
{block scripts} z @layout.latte proběhne, ajax se zavolá, ale
objeví se chyba
„NetworkError: 500 Internal Server Error – http://localhost/ajax3/www/?…“ – Possible problem: you
are sending a HTTP header while already having some data in output buffer. Try
Tracy\OutputDebugger or start session earlier.
Jak správně propojit @layout.latte a default.latte?
Editoval aum (19. 10. 2016 15:57)
- jiri.pudil
- Nette Blogger | 1032
@aum @CZechBoY tě chtěl požádat, abys zdrojové kódy na fóru zapisoval tak, aby se daly pohodlně číst – zvýšíš tím šanci, že ti někdo poradí :)
- Jan Mikeš
- Člen | 771
Pokud nemáš v šabloně uvedeno {extends none}
tak hledá
svůj „layout“ a to v tomto pořadí: https://api.nette.org/…ter.php.html#…
Zjednodušeně v praxi to znamená, že hledá toto:
Presenter.@layout.latte
@layout.latte
ve stejném
adresáři, o adresář výše atd… (více ti řekne ten
zdrojový kód).
Pokud tuto funkci nepřepisuješ, nebo nepoužíváš makro
{extends}
nebo {layout}
nemusíš se tedy
o propojení s @layout.latte starat, protože proběhne
automaticky.
Proto si v šabloně default.latte definuješ
{block content}
ten se totiž vloží na příslušné místo
právě do @layout.latte a
to {include content}
Určitě bych doporučil přečíst si o dědičnosti šablon více v dokumentaci: https://latte.nette.org/cs/tags#…
Ujisti se, že si v default.latte nepřepisuješ
{block scripts}
, nebo že v něm voláš
{include parent}
.
Já js řeším tak, že knihovny, které potřebuji všude mám mimo block a
pod nimi mám prázdný {block js}{/block}
který právě čeká na
naplnění z potomků layoutu.
Editoval Lexi (20. 10. 2016 0:19)
- aum
- Člen | 12
@premek_k: Promiň, už jsem zkoušel mnoho variant a zmýlil jsem se. Ajax v tvém řešení jede ale objeví se ta chyba “NetworkError: 500 Internal Server Error – http://localhost/ajax3/www/…” – Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.
@Lexi: Dík, takhle nějak jsem si to myslel. Nerozumím ale tomu, proč když v default.latte nemám <div> blok obalený {block content}em, knihovny v @layout.latte se nanačtou.
- Jan Mikeš
- Člen | 771
@aum měl by jsi veškerý svůj kód strukturovat do blocků, pokud
tak neučiníš a tvá šablona začíná přímo HTML kódem, o tuto
dědičnost přijdeš a neextenduje se @layout.latte ale
využívá se pouze šablona, ve tvém případě default.latte
(Narozdíl od layoutů, ty mohou začínat přímo HTML kódem. Layout
poznáš tak, že zpravidla v názvu souboru je použit zavináč, pokud budeš
ale moc chtít, tak i tato jmenná konvence se dá změnit.)
Co se týká chyby s brzkým odesláním HTTP headeru: nevypisuješ někde
něco v php pomocí echo
nebo jiné funkce?
Doporučuji vyzkoušet taktéž v config.neon
startovat
session dříve pomocí:
session:
autoStart: true # výchozí hodnota je 'smart'
Pokud by jsi byl úplně v koncích, zkus řešení uvedené na https://phpfashion.com/…-nette-2-2-3
A do pětice všeho dobrého: při vývoji můžete narazit na upozornění Possible problem: you are sending a HTTP header while already having some data in output buffer. Try OutputDebugger or start session earlier. To se objeví, když se snažíte odeslat HTTP hlavičky, a ono to sice ještě jde, nicméně aplikace už nějaký výstup předtím odeslala, jen ho zachytil output buffer. V takové situaci je nejlepší nastartovat OutputDebugger a zjistit, odkud se výstup posílal a předejít tomu. Od verze 2.2.3 máte také možnost toto dobře míněné upozornění potlačit pomocí proměnné Nette\Http\Response::$warnOnBuffer. Třeba opět z bootstrapu:
$container->getByType('Nette\Http\Response')->warnOnBuffer = FALSE;
Z praxe ale vím, že programátoři jsou lidé zvídaví a jsou 2 stavy, které je nenechávají klidným:
- Něco mi nefunguje a nevím proč
- Něco mi funguje a nevím proč :-)
Editoval Lexi (20. 10. 2016 5:18)
- premek_k
- Člen | 172
Co se týká chyby s brzkým odesláním HTTP headeru: nevypisuješ někde něco v php pomocí echo nebo jiné funkce?
Přesně tak- pokud tam máš nějaké ladící dumpy, tak odstranit. Problém může dělat i notice nebo jiná chyba, která vypadne ze serveru. Jednoduše to odhalíš v konzoli chromu na záložce „síť“, když se podíváš na response toho volání. Musí tam být jen čistý json. Ty tam před ním budeš mít něco „navíc“.
- redbulliik
- Člen | 3
Ahoj, mám raké problém zprovoznit příklad https://doc.nette.org/…ication/ajax
Nad snippet input type text, a po kliknutí na change variable se mi reloaduje
celá stránka.
podmínka:
<?php
if ($this->isAjax()) {
$this->redrawControl('ajaxChange');
}
?>
je negativní, ale i když odstranim podmínku a enchám pouze redraw, tak
se mi reloaduje celá stránka.
sandndbox jsem stahl z https://nette.org/cs/packages a
nette.ajax.js z : https://github.com/…ette.ajax.js
(zkopírovaný kod z náhledu souboru).
Má někdo tento příklad odskoušený? Se snippety začínám a nevím si
stím rady.
Kód je přesně zkopírovaný z návodu a postupoval jsem tam, abych nic
nezapoměl a nefunguje mi to, jak má.
Děkuji za každou pomoc.