Snippet in a snippet doesn't see a varible
- netteman
- Member | 125
Hi,
this is what I'm trying to achieve
- user load the page
- an ajax request loads information from database and appends it to the first snippet (several rows)
- a user can try to load updated information by clicking on a link (only one row is loaded and changed in DOM)
<div n:snippet="newText" data-ajax-append="true">
{ifset $ajaxTexts}
{foreach $ajaxTexts as $text}
{$text->text}<br />
<li n:snippet="item-$text->id">{$text->text} <a class="ajax" n:href="update! $text->id">update</a></li>
{/foreach}
{/ifset}
</div>
I can't get the “clicking part” working because Nette says $text is undefined.
This example with snippets within a snippet works https://doc.nette.org/…ication/ajax#… but when I add the AJAX append the inner snippet doesn't see the variable.
Can I make it work somehow? Thanks :)
Last edited by netteman (2016-07-04 15:38)
- David Matějka
- Moderator | 6445
Hi, could you please show the compiled template (it's in a
/temp/cache/latte
directory)?
- David Matějka
- Moderator | 6445
@DavidGrudl I think it's not. <li>
is a dynamic
snippet so the $text
variable should be visible.
- netteman
- Member | 125
New behaviour of the page (the code is the same): it doesn't say that $text is undefined anymore. This time the presence of the inner snippet corrupts the JSON response
For David Matějka: cached latte
<?php
use Latte\Runtime as LR;
class Template51785242ca extends Latte\Template
{
public $blocks = [
'content' => 'blockContent',
'_newText' => 'blockNewText',
];
public $blockTypes = [
'content' => 'html',
'_newText' => 'html',
];
function render()
{
// prolog Latte\Macros\CoreMacros
if ($this->initialize($_args)) return;
extract($_args);
if (isset($this->params['text'])) trigger_error('Variable $text overwritten in foreach on line 22');
// prolog Nette\Bridges\ApplicationLatte\UIMacros
if (Nette\Bridges\ApplicationLatte\UIRuntime::initialize($this, $this->blockQueue)) return;
// main template
call_user_func(reset($this->blockQueue['content']), get_defined_vars());
?>
<?php
}
function prepare()
{
extract($this->params);
$this->parentName = $this->parentName ?: ($this->blocks && !$this->getReferringTemplate()
&& isset($this->global->uiControl) && $this->global->uiControl instanceof Nette\Application\UI\Presenter
? $this->global->uiControl->findLayoutTemplateFile() : NULL);
return get_defined_vars();
}
function blockContent($_args)
{
extract($_args);
?>
Once upon a time... <br>
<div data-ajax-append="true"<?php echo ' id="' . $this->global->uiControl->getSnippetId('newText') . '"' ?>>
<?php call_user_func(reset($this->blockQueue['_newText']), $this->params) ?>
</div>
<?php
/* line 32 */ $_tmp = $this->global->uiControl->getComponent("textForm");
if ($_tmp instanceof Nette\Application\UI\IRenderable) $_tmp->redrawControl(NULL, FALSE);
$_tmp->render();
?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
<script src="<?php echo LR\Filters::escapeHtmlAttr(LR\Filters::safeUrl($basePath)) /* line 35 */ ?>/js/main.js"></script>
<script src="<?php echo LR\Filters::escapeHtmlAttr(LR\Filters::safeUrl($basePath)) /* line 36 */ ?>/js/nette.ajax.js"></script>
<script>
$(function () {
$.nette.init();
});
$(document).ready(
function() {
$.nette.ajax({
url: '?do=firstLoad&roomId=2'
})
});
$(document).ready(
function() {
setInterval(function(){
$.nette.ajax({
url: '?do=newText&roomId=2'
})
}, 10000);
});
</script>
<?php
}
function blockNewText($_args)
{
extract($_args);
$this->global->uiControl->redrawControl('newText', FALSE);
?> <?php
if (isset($ajaxTexts)) {
?>
<?php
$iterations = 0;
foreach ($ajaxTexts as $text) {
?> <?php echo LR\Filters::escapeHtml($text->text) /* line 23 */ ?><br>
<li<?php echo ' id="' . ($this->global->dynSnippetId = $this->global->uiControl->getSnippetId("item-$text->id")) . '"' ?>><?php
ob_start();
echo LR\Filters::escapeHtml($text->text) /* line 24 */ ?> <a class="ajax" href="<?php echo LR\Filters::escapeHtmlAttr($this->global->uiControl->link("update!", [$text->id])) ?>">update</a><?php
$this->global->dynSnippets[$this->global->dynSnippetId] = ob_get_flush();
?></li>
<?php
$iterations++;
}
}
if (isset($this->global->dynSnippets)) return $this->global->dynSnippets;
}
}
This is the working JSON response of firstLoad() – no inner snippets in the template
snippet--newText:"
first<br>
second<br>
third<br>"
This is the probably corrupted JSON response of firstLoad() – inner snippets are part of the template
snippet--item-1:"first <a class="ajax" href="/storry-2/www/room/default/1?roomId=2&do=update">update</a>"
snippet--item-2:"second <a class="ajax" href="/storry-2/www/room/default/2?roomId=2&do=update">update</a>"
snippet--item-3:"third <a class="ajax" href="/storry-2/www/room/default/3?roomId=2&do=update">update</a>"
- David Matějka
- Moderator | 6445
This response is expected. I think you will have to write custom JS success handler for appending new items.