Vnořené snippety – prý nejdou, takže jak to napodobit?
- medhi
- Generous Backer | 255
Ahoj, moc mi chybí možnost vnořených snippetů. Mám totiž tento případ:
Galerie fotek – jednotlivé fotky se prohlížejí ve snippetu (předchozí, další). Ke každé fotce chci však dát widget Voter, což je control – hlasovátko, které samo o sobě je snippetované. To už máme ale dva snippety v sobě, a tak hlasovátko nefunguje. Podařilo se mi pouze rochodit u něj handle, takže zahlasuje, ovšem už se nepřekreslí.
Netuším, jak tento případ jinak elegantně vyřešit, pomůžete? Nebo snad brzy půjdou vnořovat snippety?
Nette: 0.9.4
- Matúš Matula
- Člen | 257
Vo verzii 0.9.0 alebo mozno aj 0.9.1 to funguje, neviem, ci aj oficialne,
ale mne to slape a vlastne len kvoli tomu som nepresiel na novsiu verziu..
to vnorovanie by sa fakt hodilo..
- Mikulas Dite
- Člen | 756
Jako workaround se dá použít jeden snippet navíc, tzn rozdělit to na část před hlasovadlem, to a část po něm. Je to ale divný invalidovat. (Plus je to nesmysl, když je jich víc než dva, resp. tři).
Ale vnořené snippety by byly dobré, to jo.
- Ola
- Člen | 385
Pokud to hlasovátko bude komponenta, pak by mohlo/mělo (ale not sure) jít vložit snippet do šablony tý komponenty. Tedy pak by šablona view mohla vypadat třeba takhle:
@{block #content}
{snippet something}
Jedna
{widget someVoterControl}
Dva
{/snippet}
A widgetu:
{snippet}
<a href="{link vote}">Hlasuj</a>
{/snippet}
Mám pocit, že v trošku starší verzi jsem přesně tohle používal.
Editoval Ola (10. 5. 2010 20:11)
- Matúš Matula
- Člen | 257
Ola napsal(a):
Pokud to hlasovátko bude komponenta, pak by mohlo/mělo (ale not sure) jít vložit snippet do šablony tý komponenty. Tedy pak by šablona view mohla vypadat třeba takhle:
@{block #content} {snippet something} Jedna {widget someVoterControl} Dva {/snippet}
A widgetu:
{snippet} <a href="{link vote}">Hlasuj</a> {/snippet}
Mám pocit, že v trošku starší verzi jsem přesně tohle používal.
Ano, o tomto som pisal aj ja. V novsich verziach to prestalo chodit, tusim som to skusal iba na 0.9.2
- medhi
- Generous Backer | 255
public function handleVote($value, $id)
{
Votes::vote();
if(!$this->presenter->isAjax())
{
$this->redirect('this');
}
else
{
$this->invalidateControl('voter');
}
}
Když to sleduju v konzoli Firebugu, tak to vrací
prádno: {"state":[]}
To vypadá, že mám někde jenom nějako blbost…
- Ola
- Člen | 385
Zkusil jsem to hodit do archivu: (PHP 5.3)
http://leteckaposta.cz/584155443
EDIT: nějak sem si tam hrál s tím invalidateControl, je možný že sem tam nechal invalidaci u presenteru, fungovat by mělo obojí
Editoval Ola (10. 5. 2010 22:18)
- medhi
- Generous Backer | 255
A zjistil jsem, že to nemá vůbec co dělat se vnořenými snippety. Ten obalový snippet tam ani nemusí být a přesto se widget nepřekresluje. Stačí, když je umístěn v podmínce, která ho zobrazí pouze na základě nějakého signálu.
Stručně:
Presenter:
<?php
public function handleShowMe()
{
$this->template->showMe = TRUE;
}
?>
Template:
@{if isset($showMe)}
@{widget voter}
@{/if}
Template voteru:
{snippet voter}
<a href="{link Vote!}">Vote</a>
{/snippet}
Pokud invaliduji widget voter, tak se widget nepřekreslí.
Dělám to nějak blbě nebo je to vlastnost nebo je to bug?
- wdolek
- Člen | 331
uff, zrovna resim neco podobneho a take jsem narazil – vysledek „thready“ by me velice zajimal… ( trhead: https://forum.nette.org/…uzit-snippet )
vytvoril jsem komponentu GalleryRecord
ktera vypisuje jeden
zaznam galerie. pod zaznamem je pak snippet, ktery pouziva tu samou komponentu
k vykresleni pod-galerii.
vsiml sem si, ze na 1. urovni Nette vygeneruje nazvy snippetu
snippet-galleryRecord-sub_17
, na 2. urovni uz nazev snippetu
vypada takto snippet-galleryRecord-galleryRecord-sub_18
… nemuze
byt problem prave v tom? (jen ma domnenka, koukal sem do zdrojaku
Control
a moc jsem z toho moudry nebyl, co tam probiha).
na 2. urovni taktez dostanu prazdnou JSONi odpoved :P … myslel sem, ze za to
muzou ty proklate zavinace. zoufale sem pak zkusil (nehlede na thread od pandy
o zavinacove magii) snad vsechny kombinace s/bez zavinacu, ale ani tuk.
GalleryRecord.php
<?php
/**
* Gallery record control
*/
class GalleryRecord extends Control {
/**
* @var \Foo\Models\Content\Gallery
*/
private $gallery = NULL;
/**
* @var array of \Foo\Models\Content\Gallery
*/
private $childGalleries = NULL;
/**
* @param \Foo\Models\Content\Gallery $gallery
* @param bool $isOdd
* @return void
* @throws \InvalidArgumentException
*/
public function render($gallery, $isOdd = NULL, $level = 1) {
if (!($gallery instanceof Gallery)) {
throw new \InvalidArgumentException('Instance of Gallery must be passed!');
}
$this->gallery = $gallery;
// template
$template = $this->template;
$template->setFile(__DIR__ . '/GalleryRecord.phtml');
// properties
$template->gallery = $gallery;
$template->galleryId = $gallery->getId();
$template->childGalleries = $this->childGalleries;
$template->isOdd = (bool) $isOdd;
$template->level = max(1, intval($level));
// render
$template->render();
}
/**
* @return void
*/
public function handleSubTree($parentGalleryId) {
$galls = Gallery::find(NULL, NULL, array(Gallery::FIELD_ID_PARENT => $parentGalleryId));
// wrap to array
if (!is_null($galls) && !is_array($galls)) {
$galls = array(
$galls->getId() => $galls
);
}
$this->childGalleries = $galls;
if ($this->presenter->isAjax()) {
$this->invalidateControl('sub_' . $parentGalleryId);
}
}
/**
* @return \GalleryRecord
*/
public function createComponentGalleryRecord() {
return new self;
}
}
GalleryRecord.phtml
<div class="record{if $isOdd} odd{/if}" style="margin-left: {=(($level - 1) * 30)}px;">
...
</div>
@{if $gallery->hasChild()}
{snippet sub_$galleryId}
@{if $childGalleries}
@{foreach $childGalleries as $g}
@{widget galleryRecord $g, $iterator->isOdd(), ($level + 1)}
@{/foreach}
@{/if}
{/snippet}
@{/if}
- Aurielle
- Člen | 1281
Zavináče do snippetu nepatří, viz https://forum.nette.org/…agie-v-praxi.
edit: je to jen konstatování, v ajaxu se prozatím moc nevyznám, takže je
možná v tomto směru moje odpověď bezvýznamná.
Editoval gmvasek (21. 5. 2010 10:32)
- Honza Kuchař
- Člen | 1662
Projdi si kód a zjistíš, jak to funguje. Hledej SnippetHelper. Případně to bylo na nějakém videu z poslední soboty. Je tady na wiki.
- wdolek
- Člen | 331
Honza Kuchař: muzu se zeptat, kterepak je to video? skoukl sem vsechny uvadene PS, (vcetne PS o Adobe Fireworks a Enterprise Architect :D), ale nikde se problematika vnorenych snippetu neresila
do zdrojaku jsem take koukal, ale stale nic nevykoukal. v tutorialech, FAQ, ani v prirucce programatora jsem take nenasel nic konkretniho, co by resilo podobnou situaci.
- Honza Kuchař
- Člen | 1662
Myslím, že je to i někde tu na wiki, ale jisto jistě je kopie i mu mě na server: http://projekty.mujserver.net/…ardubice%29/
- wdolek
- Člen | 331
Honza Kuchař: tak abych pravdu rekl, nejak mi to k reseni meho problemu nepomohlo… ze mohu includnout sablonu samu v sobe je sice pekne, jenze – vytvoreni Controlu se sablonou, v ktere je snippet, ktery vytvari novou instanci toho sameho Controlu (widgetu), ktery pouziva tu samou sablonu… … a ktery se pak ajaxove invaliduje… to nejak nevyresilo :(
… a protoze to asi nedovedu poradne vysvetlit, tady je videjko: http://storage.wdolweb.cz/…_snippet.ogv
- prvni AJAXovy dotaz dostane odpoved,
- druhy AJAXovy dotaz uz odpoved nedostane (neprovede se invalidace – payload neobsahuje pole snippetu, ktere se maji prekreslit (a obsah prekresleni))
GalleryRecord
reprezentuje jeden radek v tabulce (jeden zaznam,
jednu galerii).
handler controlu GalleryRecord
:
public function handleSubTree($parentGalleryId) {
$galls = Gallery::find(NULL, NULL, array(Gallery::FIELD_ID_PARENT => $parentGalleryId));
// wrap to array
if (!is_null($galls) && !is_array($galls)) {
$galls = array(
$galls->getId() => $galls
);
}
$this->childGalleries = $galls;
if ($this->presenter->isAjax()) {
$this->invalidateControl('sub_' . $parentGalleryId);
}
}
sablona controlu (2. – N. uroven):
<!-- vypis radku v <div> ... -->
...
<!-- snippet, pokud ma galerie decka -->
@{if $gallery->hasChild()}
{snippet sub_$galleryId}
{if $childGalleries}
{foreach $childGalleries as $g}
{widget galleryRecord $g, $iterator->isOdd(), ($level + 1)}
{/foreach}
{/if}
{/snippet}
@{/if}
sablona, ktera zobrazuje seznam galerii (1. (korenova) uroven):
<ul class="list">
@{foreach $galleries as $g}
<li>
@{widget galleryRecord $g, $iterator->isOdd()}
</li>
@{/foreach}
</ul>
zkusil sem vypnout uplne JS – a skutecne neni chyba nekde v generovani
jmena snippetu? ackoliv vse v HTML a controlu sedi (zkousel sem si vypsat
getSnippetId(...)
, dostavam odkazy:
odkaz na korenove galerii pro zobrazeni pod galerii:
?galleryRecord-parentGalleryId=17&language=cs&do=galleryRecord-subTree
odkaz na druhou uroven galerii, pro zobrazeni 3. urovne:
?galleryRecord-galleryRecord-parentGalleryId=18&language=cs&do=galleryRecord-galleryRecord-subTree
a ackoliv v HTML je snippet pojmenovan
snippet-galleryRecord-galleryRecord-sub_18
tak je zvlastni to
zdvojeni nazvu controlu –
galleryRecord-galleryRecord-subTree
– kdyz zkusim tuto akci
spustit neAJAXove, dostanu akorat vynadano… neni prave toto ten duvod, proc
nedostavam zadnou odpoved? (na druhou stranu to ale nehaze ani zadnou 500)
Editoval wdolek (24. 5. 2010 23:44)