Snippet uvnitř komponenty

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
phe02
Člen | 2
+
0
-

Ahoj,
mám problém s překreslením snippetu uvnitř komponenty při AJAXu. Komponenta je uvnitř šablony, která je odkazovaná z jiné šablony (ale vnoření šablon na celou věc nejspíš vliv nemá).
Šablona komponenty ExchangeRates.latte:

{block content}
	<article>
		<h1 class="red">
			Control - title ({$id})
		</h1>

		<form action="#" method="get" class="exchange-filter">
			<div class="row">
				<div class="col-sm-6">
					{foreach ['A', 'B'] as $opt}
						<div class="radio-wrapper">
							<label>
								<input type="radio" name="mode" class="modesel" {$id == $opt ? 'checked="checked"' : ''|noescape} value="{$opt}">
								{$opt}
							</label>
						</div>
					{/foreach}
				</div>
			</div>
		</form>

		<div n:snippet="xchgchart">
			<div class="padding-30-0" {$id == 'A' ? 'style="background-color: lightskyblue"' : 'style="background-color: lightpink"'|noescape}>
				{$id} selected
			</div>
		</div}

	</article>
{/block}

{block scripts}
	<script>
		$('.modesel').on('change', function () {
			var val = $(this).val();
			var str = {$presenter->link('default', 'XXX')};  // varianta #1
			// var str = {$control->link('radio!', 'XXX')};  // varianta #2
			var url = str.replace('XXX', val);
			$.nette.ajax({
				type: 'GET',
				url: url,
				data: {}
			});
		});
	</script>
{/block}

Kód komponenty:

<?php
...
    public function renderChart($id)
	{
        $this->template->id = $id;
        $this->template->setFile(__DIR__ . '/ExchangeRates.latte');
        $this->template->render();
    }

	// pro AJAX variantu #2
    public function handleRadio($id)
    {
        $this->template->id = $id;
        $this->redrawControl('xchgchart');
    }

...
?>

Kód presenteru – pro HTTP request a AJAX variantu #1

<?php
...
    public function renderDefault($id)
    {
        $this->template->id = $id;
        $this->setView('exchange');
        if ($this->isAjax()) {
            //$this->redrawControl('child_wrapper');  // prekvapive neni potreba ???
            $this->redrawControl('control_wrapper');
            $this['exchangeRates']->redrawControl('xchgchart');
        } else {
            $this->redrawControl();
        }
    }
...
?>

@layout.latte

{includeblock '@head.latte'}
{includeblock '@header.latte'}

<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{_ 'messages.flashMessage.' . $flash->message}</div>

<div class="" id="loading"></div>
<div n:snippet="content" class="transition-fade transition-auto">
    {snippetArea child_wrapper}
        {include content}
    {/snippetArea}
</div>

{includeblock '@footer.latte'}
{includeblock '@tail.latte'}

exchange.latte

{block content}
<main>
	{snippet bread}
    <section class="breadcrumbs">
        <div class="guide">
            Breadcrumb snippet: {$id}
        </div>
    </section>
	{/snippet}

    <section class="exchange">
        <div class="container">
            <div class="row padding-40-0">
                <div class="col-sm-8 col-md-9 content">
					{snippet control_wrapper}
						{control exchangeRates:chart, $id}
					{/snippet}
				</div>
            </div>
        </div>
    </section>
</main>
{/block}

Pokud se v exchange latte neobalí řádek s komponentou ‚{control exchangeRates:chart, $id}‘ do snippetu, AJAX nepošle nic. Obalí-li se místo toho do snippetArea, AJAX nepošle také nic. Ale jakmile přidám ten snippet (control_wrapper), pošle se vždycky jen celý obsah komponenty, ne jenom její snippet xchgchart, jak bych si v ideálním případě představoval.
Při invalidaci snippetů z presenteru (varianta #1) nelze vynechat řádek ‚$this->redrawControl('control_wrapper‘);', jinak framework zkouší volat na neexistující metodu komponenty render(), navíc bez parametrů.
Pokud změním URL pro AJAX z presenter/request na komponenta/signál (tzn. variantu #1 na #2), dopadne to zhruba stejně.
Můžete mi někdo prosím poradit, co dělám blbě?

CZechBoY
Člen | 3608
+
+2
-

V ajaxu se moc ty parametry a jiný rendery nedaj použít, protože se volá prostě render() a nic jinýho z toho nedostaneš. Jedině, že bys invalidoval ty snippety nějak sám (o co se asi snažíš).
Doporučuju předávat parametry konstruktorem a v šabloně mít jen render, případně Multiplier.

David Matějka
Moderator | 6445
+
+2
-

A dle tveho prikladu je zbytecne predavat ID az v sablone. Jelikoz ho znas uz v presenteru, tak to muzes predat pri vytvareni komponenty.

phe02
Člen | 2
+
0
-

Díky vám oběma. Že by správná komponenta pro Ajax měla být „blbá“ bylo řečeno i na posobotním videu „Snippety – proč a jak (ne)fungují“, jak jsem zjistil později. Hlavně ale po předělání komponenty na bezparametrovou se teď dá invalidovat jen samotný snippet ‚xchgchart‘ uvnitř komponenty, její obalení snippetem ‚control_wrapper‘ se může zrušit a v Ajax response dostanu přesně ten správný obsah.
Úplně tu souvislost nechápu, ale to nevadí.
Díky.