Podivné chování snippetů – invalidace vrátí NULL

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

Ahoj, narazil jsem na následující problém – používám „staré“ snippety (řídil jsem se dokumentací a příklady na fóru) a povedlo se mi rozchodit AJAX. Přesto se spinner někdy nezmizí a invalidovaný snippet vrátí null… napadá mě snad jen chyba v zavináčích, řídil jsem se návodem na zavináčovou magii, ale přesto je možné, že mi něco uniklo… (zvlášť si nejsem jistý v Před příkazy, které nějakým způsobem ovlivňují obsah, který ve snippetu vykreslujeme)

Nette 1.0-alpha, dibi 1.3 dev
Metoda v presenteru:

public function handleServerDetails($id)
{
	$this->template->server = Servers::find($id);
	$this->template->serverInfo = ServerInfo::find($id);
	$this->template->players = ServerInfo::findPlayers($id);

	Debug::fireLog((array) $this->template->server);
	Debug::fireLog((array) $this->template->serverInfo);
	Debug::fireLog((array)$this->template->players);

	$this->invalidateControl('serverdetails');
}

Šablona:

{block #contenttitle}Přehled serverů{/block}
@{block #content}
{snippet serverdetails}
{if isset($server)}
<div id="server-details">
{if isset($serverInfo->hostname)}
{assign $players ServerInfo::findPlayers($server->sid)}
<table style="width: 750px; margin: 0 auto">
	<tr>
		<td style="vertical-align: top">
			<table style="width: 100%;">
				<tr>
					<th>Jméno</th>
					<th style="width: 10%">Skóre</th>
					<th style="width: 30%">Čas</th>
				</tr>
				{if !empty($players)}
				{foreach $players as $player}
				<tr id="s{$server->sid}p{$player['index']}">
					<td>{$player['name']}{if $user->hasFlag(ADMIN_ADD_BAN)} (<a href="{plink :Viewer:Admin:Servers:kick sid => $server->sid, name => $player['name']}">kick</a> - <a href="{plink :Viewer:Admin:Bans:add sid => $server->sid, name => $player['name']}">ban</a>){/if}</td>
					<td>{$player['kills']}</td>
					<td>{$player['time']}</td>
				</tr>
				{/foreach}
				{else}
				<tr>
					<td colspan="3" style="text-align: center; font-size: 11px; font-weight: bold">
					Na serveru právě nehrají žádní hráči.
					</td>
				</tr>
				{/if}
			</table>
		</td>
		<td style="width: 355px; text-align: center;">
			{if file_exists(WWW_DIR . '/images/maps/' . $serverInfo->map . '.jpg')}
			<img src="{$basePath}/images/maps/{$serverInfo->map}.jpg" alt="{$serverInfo->map}" width="340" height="255" />
			{else}
			<img src="{$basePath}/images/maps/nomap.jpg" alt="{$serverInfo->map}" width="340" height="255" />
			{/if}
			<br /><br />
			<strong style="font-size: 11px; display: block">{$server->ip}:{$server->port}</strong>
			<a href="steam://connect/{$server->ip}:{$server->port}" class="submitbutton" style="background-image: url({$basePath}/images/connect.gif); font-size: 11px; color: black; margin: 4px auto; display: block; width: 120px">Připojit se na server</a>
		</td>
	</tr>
</table>

	{assign $mod Mods::find($server->modid)}
	<span id="fancybox-title-over" style="color: white; margin-top: 10px">
		<img src="{$basePath}/images/games/{$mod->icon}" alt="{$mod->name}" style="vertical-align: middle" />
		<img src="{$basePath}/images/{$serverInfo->os}.png" alt="" style="vertical-align: middle" />
		{if $serverInfo->secure}<img src="{$basePath}/images/shield.png" alt="Secured" style="vertical-align: middle" />{/if}
		|
		{$serverInfo->hostname}
		|
		{$serverInfo->numplayers}/{$serverInfo->maxplayers}
		|
		{$serverInfo->map}
		<br />
		{$server->ip}:{$server->port}
	</span>
{else}
<div style="text-align: center; font-weight: bold; padding: 5px 10px">chyba připojování ({$server->ip}:{$server->port})</div>
{/if}
</div>
{/if}
{/snippet}
<table id="servers">
	<tr>
		<th style="font-weight: normal; width: 2%">Hra</th>
		<th style="font-weight: normal; width: 2%">OS</th>
		<th style="font-weight: normal; width: 2%">VAC</th>
		<th style="text-align: center">Jméno serveru</th>
		<th style="width: 10%">Počet&nbsp;hráčů</th>
		<th style="width: 13%">Mapa</th>
	</tr>
	{foreach $servers as $server}
	{assign $mod Mods::find($server->modid)}
	{assign $serverInfo ServerInfo::find($server->sid)}
	<tr class="server-info ajax" id="server-{$server->sid}">
		<td style="text-align: center">
			<img src="{$basePath}/images/games/{$mod->icon}" alt="{$mod->name}" style="vertical-align: middle" />
		</td>
		{if $serverInfo === FALSE}
		<td style="text-align: center">N/A</td>
		<td style="text-align: center">N/A</td>
		<td><em style="color: #677882">chyba připojování ({$server->ip}:{$server->port})</em></td>
		<td>N/A</td>
		<td>N/A</td>
		{else}
		<td style="text-align: center">
			<img src="{$basePath}/images/{$serverInfo->os}.png" alt="" style="vertical-align: middle" />
		</td>
		<td style="text-align: center">
			{if $serverInfo->secure}<img src="{$basePath}/images/shield.png" alt="Secured" style="vertical-align: middle" />{/if}
		</td>
		<td>
			{$serverInfo->hostname}
		</td>
		<td>{$serverInfo->numplayers}/{$serverInfo->maxplayers}</td>
		<td>{$serverInfo->map}</td>
		{/if}
	</tr>
	{/foreach}
</table>

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
	$('#server-details').hide();
});

$('tr.ajax').live('click', function(event) {
	event.preventDefault();
	if ($.active) return;

	$.post({link serverDetails!}, { id: this.id.substr(7) }, function(payload) {
		$.nette.success(payload);
		$('#server-details').hide();

		$.fancybox($('#server-details').html(), {
			'autoDimensions': true,
			'autoScale': false,
			'scrolling': 'no',
			'onComplete': function() {
				$.fancybox.resize();
			}
		});
	});

	$.nette.spinner.css({
		position: 'absolute',
		left: event.pageX,
		top: event.pageY
	});
});
//]]>
</script>
@{/block}

{block #title}Servery{/block}
Aurielle
Člen | 1281
+
0
-

Ještě přidám výstup z firebugu: http://upload.snadno.net/…rebug1a8.png

edit: v layoutu samozřejmě je @{include #content}

Editoval gmvasek (11. 6. 2010 18:41)

Ondřej Mirtes
Člen | 1536
+
0
-

Asi bych ten příklad osekal na minimum, při kterém to ještě nebude fungovat, tohle je moc kódu na zkoumání a udělání chyby.

Aurielle
Člen | 1281
+
0
-

Tak po copy&pastování na produkční server a hledání chyby jsem dospěl k tomu, že neodeslání snippetu způsobil nejspíše neznámý znak (ne UTF-8) ve jménu hráče.
 Řádek

<td>{$player['name']}{if $user->hasFlag(ADMIN_ADD_BAN)} (<a href="{plink :Viewer:Admin:Servers:kick sid => $server->sid, name => $player['name']}">kick</a> - <a href="{plink :Viewer:Admin:Bans:add sid => $server->sid, name => $player['name']}">ban</a>){/if}</td>

jsem opravil na:

<td>{=String::fixEncoding($player['name'])}{if $user->hasFlag(ADMIN_ADD_BAN)} (<a href="{plink :Viewer:Admin:Servers:kick sid => $dServer->sid, name => $player['name']}">kick</a> - <a href="{plink :Viewer:Admin:Bans:add sid => $dServer->sid, name => $player['name']}">ban</a>){/if}</td>

a vypadá to, že se snippet již vždy odešle. Proč se ovšem to jméno vypíše v nezměněné podobě do linku korektně, to netuším.