redrawControl z více šablon

Damo
Člen | 55
+
0
-

Ahoj, potřeboval bych si vrátit snippety z více šablon, ale nevím jak tu druhou tám dát. Takto jak uvádím, mi to vrátí celou šablonu.

díky

public function actionDefault(): void {
        $this->template->notifications = Notificaton::getNotifications(10);
        $this->postGet("this");
        $this->redrawControl("systemNotificationsIndicator");
        $this->redrawControl("systemNotificationsHeader");
        $this->redrawControl("systemNotificationsMessages");
        $this->redrawControl("systemNotificationsFooter");

		// zde potrebuji nacíst druhou sablonu, vyrendrovat a do payload nahrat jen ten jeden snippet co v te sablone je "notificationsService"
		// tento priklad samozrejme nahraje do payload celou sablonu
        $secondTemplate = $this->createTemplate();
        $secondTemplate->setFile(__DIR__ . "/templates/Notification/service.latte");
        $secondTemplate->serviceSettings = ServiceSettings::get();
        $snippetContent = $secondTemplate->__toString();
        $this->payload->snippets["notificationsService"] = $snippetContent;
    }
Damo
Člen | 55
+
0
-

Pokud na to není nějaká jednoduchá věc, tak jsem to vyřešil takto

    public function actionDefault(): void {
        $this->template->notifications = Notificaton::getNotifications(10);
        $this->postGet("this");
        $this->redrawControl("systemNotificationsIndicator");
        $this->redrawControl("systemNotificationsHeader");
        $this->redrawControl("systemNotificationsMessages");
        $this->redrawControl("systemNotificationsFooter");

        $snippetRender = new SnippetRender($this);
        $snippetRender->template->setFile(__DIR__ . '/templates/Notification/service.latte');
        $snippetRender->template->serviceSettings = ServiceSettings::get();
        $snippetRender->redraw(["notificationsService"]);
    }
<?php

declare(strict_types=1);

namespace App\Models\Snippet;

use DOMDocument;
use DOMElement;
use Nette\Application\UI\Control;
use Nittro\Bridges\NittroUI\Presenter;

class SnippetRender extends Control {

    private Presenter $presenter;

    public function __construct(Presenter $presenter) {
        $this->presenter = $presenter;
        $this->setParent($presenter);
    }

    public function redraw(array $snippets): void {
        $dom = new DOMDocument();
        $dom->encoding = "UTF-8";
        foreach ($snippets as $snippet) {
            $snippetId = $this->getSnippetId($snippet);
            $dom->loadHTML('<?xml encoding="UTF-8">' . (string)$this->template, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
            $element = $dom->getElementById($snippetId);
            if ($element) {
                $this->presenter->payload->snippets[$snippetId] = $this->innerHtml($element);
            }
        }
    }

    private function innerHtml(DOMElement $element): string {
        $innerHTML = "";
        foreach ($element->childNodes as $childNode) {
            $innerHTML .= $element->ownerDocument->saveHTML($childNode);
        }
        return $innerHTML;
    }
}

Editoval Damo (1. 4. 2023 14:09)

Martk
Člen | 656
+
0
-

Proč potřebuješ nahrávat šablonu, která náleží akci service?

Damo
Člen | 55
+
0
-

Martk napsal(a):

Proč potřebuješ nahrávat šablonu, která náleží akci service?

Nemám akci service, je to jen rozparsovana sablona a je nacítána v různých jiných sablonách, protoze se pouziva na vice mistech.

JS si v intervalech volam Presenter Notifikace, kterym si prekreslim snippety ohledne zvonecku a dropdownu se zprávami, a potrebuji prekleslit i snippet, ktery neni soucasti notifikaci. A nechci mit dva intervaly, aby mi volaly ruzne presentery. Staci mi jeden, kde si checknu notifikace do zvonecku, a k tomu service notifikaci, tak potrebuji vratit snippet. Prijde mi vhodne vyuzit uz jeden interval, co tam je, nez mit dva.

Ta šablona je jednoduchá. Potřebuji na jiným místě webu zobrazit alert, který právě potřebuji dostat do resultu té akce.

{snippet notificationsService}
    {if $serviceSettings->enabled}
        <div class="alert alert-danger m-2 p-2" role="alert"><i class="bi bi-exclamation-triangle-fill me-2"></i>{$serviceSettings->message}</div>
    {/if}
{/snippet}
Martk
Člen | 656
+
0
-

Když chci používat něco v různých šablonách, tak si to hodím do komponenty a tu překreslím. Includované snippety jsou přímo v dokumentaci https://doc.nette.org/…ication/ajax#…

Damo
Člen | 55
+
0
-

To vím, ale toto neřeší můj problém.

m.brecher
Generous Backer | 765
+
+1
-

@Damo

Ta šablona je jednoduchá. Potřebuji na jiným místě webu zobrazit alert, který právě potřebuji dostat do resultu té akce.

Ahoj, nejsem tak úplně v obraze co se týče řešeného problému, ale jestli jsem to správně pochopil, tak potřebuješ aby se při ajaxovém překreslení jedné komponenty – nějaká notifikace současně překreslila jiná komponenta – třeba notifikace na jiném místě webu?

Mám dva tipy bez záruky:

a) řešení pomocí serverových eventů:

https://archiv.pehapkari.cz/…ce-udalosti/

b) řešení pomocí javascriptové knihovny Naja, tato moderní knihovna pro ajax v Nette má pěkné rozhraní, kde se dají zachytávat a vyvolávat různé eventy a teoreticky my mohlo být možné zachytit překreslení jedné komponenty a vyvolat javascriptem překreslení jiné komponenty, já jsem třeba v jednom svém projektu zachytával v Naja překreslení komponenty a po něm vyvolal spuštění jiného javascriptu, Naja doporučuji, práce s knihovnou je snadná a dobře dokumentovaná

Z ukázky kódu vidím, že používáš pro ajax asi Nittro, což je knihovna již neudržovaná a upgradovat na Naja by asi bylo vhodné.