Řešení dynamických snippetů
- hrach
- Člen | 1838
Zápis v Latte
{foreach array(1,2,3) as $id}
{snippet rater-$id}
Rater for {$id} {=microtime(true)}
{/snippet}
{/foreach}
Je povinný formát: jmeno-$klic
Invalidace:
$this->invalidateControl('rater-2', array(
'id' => 2,
));
Invalidace je nova. Nutne:
- jmeno je opet format jmeno-klic
- druhy parametr jsou vsechny promenne, ktere maji byt v dannem snippetu dostupne a jsou zavisla na danem scope, tzn. promenne zavisle na cyklu
Toto reseni mam nyni implementovane a funkcni.
Poznamky
- nelze invalidovat vsechny dynamicke snippety zaraz, aktualni kod tento pokus jeste nehlida, bylo by dobre nejak doplnit
- pri potrebe invalidovat vsechny dynamicke snippety je resenim obalit dany cyklus vlastnim snippetem
Děkuji za návodné návrhy HosipLanovi: https://forum.nette.org/…cke-snippety#…
Co si o tom myslite?
- Patrik Votoček
- Člen | 2221
Neznám implementační detaily ale ale proč je nutné uvádět tu dvojku
2x? pokud tedy platí: Je povinný formát: jmeno-$klic
- hrach
- Člen | 1838
Jasny, chapu dotaz, zkusim rozepsat duvody k tomuto reseni.
Problém 1
Je treba jednoznacne identifikovat dany dynamick blok. K tomu se pouziva nejaky primarni klic.
Predani tohoto klice lze resit:
- predanim v nazvu snippetu
- predanim jako promenne
Prvni verzi vidite viz vyse, druha by vypadala nejak takhle:
{snippet rater, $id} // nebo
{snippet rater, id => $id}
Coz by rozbilo aktualni funkcnost s definovanim vlastniho obalovaciho tagu + by to evokovalo predavani promennych do {block}, coz je zase jina problematika.
Problem 2
V kazdem pripade bude pri ajaxovem volani treba predavat snippetu aktualni
scope. Protoze se samotny cyklus spoustet nebude.
Tedy zbyva vyresit, jestli pri beznem requestu snippetu predavat promenne jako
do {block}u, nebo danemu snippetu „pushnout“ aktualni scope. Zvolil sem
cestu 2, aby bylo co nejmene zmatku a co nejvetsi zpetna kompatibilita.
K aktualni navrhovane verzi
K duplikaci „$id“ vůbec dojit nemusi, pokud se na to podivas treba
takhle:
{foreach $items as $item}
{snippet rater-$item->id}
<h1>Item {$item->title}</h1>
{/snippet}
{/foreach}
$this->invalidateControl('rater-2', array(
'item' => ItemModel::get(2),
));
- Patrik Votoček
- Člen | 2221
už to chápu díky za vysvětlení. btw napadá mě jeden potencionální
„problém“ aka $iterator
- Patrik Votoček
- Člen | 2221
Mám takové tušení že aktuálně je to „uměle“ vypnuto. Kvůli nějakým možným komplikacím. (nevzpomenu si jaké to byly)
- hrach
- Člen | 1838
spíš nebudou :) osobně na to netlačím, pač je moc nepotřebuji, většina věcí se dá totiž vyřešit jinak a možná i efektivněji. asi by to chtělo probrat jednotlivé usecase. Tu je něco o jiných cestách: https://forum.nette.org/…v-presenteru#…
- David Grudl
- Nette Core | 8228
Podle mého se téhož dá dosáhout takto:
{foreach array(1,2,3) as $id}
{var $template->id = $id}
{snippet rater}
Rater for {$id} {=microtime(true)}
{/snippet}
{/foreach}
$this->template->id = 2;
$this->invalidateControl('rater');
- David Grudl
- Nette Core | 8228
Ok, přidal jsem tedy podporu pro dynamické snippety, mělo by to fungovat takto:
{snippet rater}
{foreach array(1,2,3) as $id}
{snippet rater-$id} // format je libovolny
Rater for {$id} {=microtime(true)} // uvnitr jsou videt promenne
{/snippet}
{/foreach}
{/snippet}
A invalidace:
$this->template->id = 2;
$this->invalidateControl('rater');
- Milanov
- Člen | 51
Toto je super, nicméně mám stránku s diskuzemi a ke každé několik komentářů. Pod komentáři je form pro odpověď. Když odpovím, chci invalidovat pouze související komentáře. V šabloně jsem doteď, úspěšně, používal tento kód (ve verzi 0.9.7 se zavináči), který jsem zkusil obalit:
{foreach ... as $disk}
{snippet komentare}
{snippet komentare-$disk['id_diskuze']}
{include 'komentare.latte', 'komentare' => $disk['komentare']}
{/snippet}
{/snippet komentare}
{/foreach}
Samozřejmě to nefunguje. Moje šablona by mezi obalovacím snippetem a
obalovaným měla obsahovat spoustu kódu, včetně jiných snippetů.
Předpokládám, že musím obalovací snippet přesunout před foreach, ale ani
v tom případě to nefunguje, šablona se přeloží jako
if (!function_exists($_l->blocks[_komentare-$disk['id_diskuze']][]
a vyhodí se Noticka s nedefinovanou konstantou. Otázka zní: lze použít
mezi obalovacím a obalovaným snippetem jiný kód? Lze vytvořit název
snippetu ve tvaru komentare-$disk[‚id_diskuze‘]? Verze Nette
Framework 2.0-beta (revision 2488680 released on 2011–06–01). Díky
- David Grudl
- Nette Core | 8228
Název snippetu musí být zapsán v uvozovkách, nebo „jako
v uvozovkách“ a bez uvozovek, tj.
{snippet "komentare-$disk[id_diskuze]"}
nebo
{snippet komentare-$disk[id_diskuze]}
.
Statický snippet je skutečně výstřižek, při vykreslování se doslova
vystřihne ze stránky a neexistuje nic před ním nebo za ním. Má-li tedy
„existovat“ nějaký foreach a proměnná $disk
, musí být
zahrnuta do statického snippetu.
Invaliduje se pouze statický snippet. Ten může vykreslit tolik dynamických, kolik potřebuje. Pokud chcete vykreslit jen 2 a 3, upravte DB dotaz tak, aby získal jen tyto data.
(neuvažujte nad tím jako: vykreslím 100 komentářů, všechny zahodím a jen dvojku pošlu ven, to je přece prasárna)