Snippet / Multiplier / zachování modal okna
- emololftw
- Člen | 82
Dobrý den / Ahoj všem,
v latte šabloně mám snippet:
{snippet deviceList}
{foreach $result->objects as $technologyId => $technologyRow}
{control "inlineChart-" . bin2hex($technologyId)}
{else}
{control nothingHere}
{/foreach}
{/snippet}
List je dynamicky vázaný na tabulku, takže je možné položku přidávat
nebo odebírat. Vše funguje bezvadně, ale problém nastává, když mám
v komponentě nějáký MODAL nebo DROPDOWN. Při každém překreslení listu
se prvek zavře. Zkoušel jsem různé {if $presenter->isAjax()}
apod. zkoušel jsem kód v komponenntě obalit snippetama, kromě zmiňovaného
modalu/dropdownu a bez výsledku. Jak řešíte Vy prvek co nechcete
překreslovat v multiplieru?
Děkuji
Edit:
Při každém překreslení v šabloně se v komponentě volá render() metoda. Bude pravděpodobně nutné vytvořit modal okno mimo komponentu?
Editoval emololftw (22. 10. 2021 15:20)
- Polki
- Člen | 553
No takto multiplier je ok i modal v komponentě je ok.
Vzhledem k tomu ale, jak fungují moderní modální okna spolu s JS, tak je dobrá praktika nepřekreslovat celý modal, ale jen jeho vnitřek. Pokud máš tedy modal uvnitř komponenty nothingHere, pak by si neměl překreslovat celou komponentu nothingHere, ale jen obsah jejího modalu. Pak ti modal zůstane otevřený a jen se změní jeho obsah.
- emololftw
- Člen | 82
Polki napsal(a):
No takto multiplier je ok i modal v komponentě je ok.
Vzhledem k tomu ale, jak fungují moderní modální okna spolu s JS, tak je dobrá praktika nepřekreslovat celý modal, ale jen jeho vnitřek. Pokud máš tedy modal uvnitř komponenty nothingHere, pak by si neměl překreslovat celou komponentu nothingHere, ale jen obsah jejího modalu. Pak ti modal zůstane otevřený a jen se změní jeho obsah.
Děkuji za odpověď. nothingHere komponenta jen zobrazí ilustraci, že zde nic není. V komponentě vykresluji pouze body modalu, ale pakliže ho má uživatel otevřené, další ajaxový požadavek na pozadí okno zavře. Chtěl bych ponechat okno otevřené, ať už přichází do komponenty jakýkoliv signál.
- emololftw
- Člen | 82
Polki napsal(a):
Důležité je nepřekreslovat snippetem samotný modal. Jen jeho obsah :)
Ano máte pravdu. V komponentě mám mnoho továrniček s repositories a
modelu. V presenteru pouze volám komponentu se setterem. Každý řádek
obsahuje právě zmíněný MODAL. Avšak při ve snippetu mám multiplier,
takže se mi vždy přepíše celá render metoda komponenty a taktéž již
zmiňovaný modal. Napadá mne vytvořit MODAL na úrovni presenteru, mimo
snippet multiplieru a v komponentě volat:
$this->getPresenter()['mainModal'] = $this->factory->create($this->rowId);
ale nevím jak moc velký je to overkill. Protože když budu mít ajaxový
formulář, půjde signál vždy do presenteru a né komponenty, kde mám
veškerou spjatou logiku. Nebo je zde možnost v komponentě definovat blok
např:` {block mainModalContent}` a tím přepisovat snippet MODAL mimo snippet
multiplieru?
Děkuji.
EDIT: obsah snippetu je pouze modal content.
<div class="modal" id="showDowntimeModal-{$control->getName()}" data-bs-keyboard="false" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{_message.form.downtimesCard.title}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4 loading-ajax-part downtimes-timeline-comment" n:snippet="downtimeModal">
<div n:snippet="flashMessages">
<div n:foreach="$flashes as $flash" n:class="alert, 'alert-'.$flash->type, fade, show">
{$flash->message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{control downtimeModal}
</div>
</div>
</div>
</div>
Editoval emololftw (23. 10. 2021 11:43)
- Polki
- Člen | 553
Já nevidím komplet celou logiku za tím, takže nemůžu jednoznačně napsat, co máš kde volat.
Důležité je však vědět, že je úplně jedno, jestli máš multiplier, nebo ne. Komponenty se chovají pořád stejně.
Například pokud chceš překreslit snippet uvnitř komponenty komentáře, což je multiplier, a ty potřebuješ překreslit obsah toho jednoho konkrétního komentáře, tak se to dělá cca takto:
$this->getComponent('comments-11')->redrawControl('content');
Kde říkáš, že comments
je multiplier a číslo
11
je v něm jedenáctá komponenta, nad kterou chceš překreslit
jen ten její jeden snippet s názvem content
.
Samozřejmě lépe se to dělá pomocí signálů směřujících přímo do té komponenty (metody formuláře), nebo pokud to potřebuješ z vnějšku, tak pomocí nějaké eventy, kterou si nadefinuješ v nějakém svém Event Managerovi.
- emololftw
- Člen | 82
Zkusím ještě otevřít toto téma. Řekl bych, že největší bottleneck jsou mé vyjadřovací schopnosti.
Mám v default.latte
snippet:
{snippet rowsArea}
{foreach $result->objects as $technologyId => $technologyRow}
{control "inlineChart-" . bin2hex($technologyRow->getOperation())}
{/foreach}
{/snippet}
tento proces volá Multiplier, kde se tvoří komponenty. Je to dynamický
seznam, uživatel může kdykoliv odebrat položku nebo jí přidat. Na pozadí
běží setInterval
a každou minutu se ajaxově přepíše celý
default.latte
. Ale každá komponenta obsahuje MODAL okno. Jsou
k tomu různé důvody, protože seznam je použitý i v jiných modulech
webu. A tím, že se zavolá redraw na seznam, se automaticky přepíše
i celý MODAL (zavolá se render metoda komponenty) a pokud má uživatel modal
otevřený, automaticky se každou minutu zavře. Komponenta vypadá
nějak takto:
<div class="modal">
<div n:snippet=modalContent>
</div>
</div>
<div class="row">
<div n:snippet=header>
</div>
<div n:snippet=result>
</div>
<div class="dropdown">
</div>
</div>
A já se právě snažil i přes snippetArea redrawnout pouze
result
a header
. Vše mi fungovalo bez problému,
dokud jsem nechtěl překreslovat celý seznam prvků kvůli jeho možnému
dynamickému chování. Ideálně bych volal jak jste zmínil:
$this->getComponent('comments-11')->redrawControl('content');
ale seznam je dynamický a přepisovat foreachem možné komponenty tak redrawnu aktivní, ale odstraněné ze seznamu nezmizí.
Děkuji.
EDIT: ještě jsem zkoušel volat v komponentě signál na přepis snippetů v dynamické komponentě, ale kvůli volání komponenty ve foreach se vždy volá render metoda a je to zbytečné, pač se kompletně modal přepíše.
EDIT2:
pokud volám:
{snippetArea rowsArea}
změn se prosím{time()}
{foreach $result->objects as $technologyId => $technologyRow}
{control "inlineChart-" . bin2hex($technologyRow->getOperation())}
{/foreach}
{/snippetArea}
tak se právě $result->objects
neaktualizuje, ale vše
ostatní tak presně jak má.
Editoval emololftw (27. 10. 2021 15:01)