Nefunguje překreslení snippetu

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

Čau, řešil jsem problém, kdy na server potřebuji pomocí javascriptu posílat array (json) id čísel a mazat je z DB
to jsem vyřešil takto

<a href="#" class="btn btn-danger btn-sm ajax" data-link="{link emailsDelete!}" data-confirm="Opravdu chcete vybrané záznamy smazat?">Smazat vybrané záznamy</a>

java script

$.nette.ajax({
	url: $(this).attr('data-link'),
	data: {
		emails: 3,
	}
});

presenter metoda

public function renderEmail()
{
	$emails = $this->database->table('emails');
	$this->template->emails = $emails;
}

public function handleEmailsDelete($emails)
{
	$this->template->emails = $this->database->table('emails')->get(3);
		$this->invalidateControl('emailTable');
		$this->redrawControl('emailTable');
}

a nakonec samotný snipet

{snippet emailTable}
	<table class="table table-striped table-hover ">
	  <thead>
	    <tr>
	      <th>#</th>
	      <th>Jméno</th>
	      <th>Příjmení</th>
	      <th>Telefon</th>
	    </tr>
	  </thead>
	  <tbody>
	  	{var $suma = 0}
	    <tr n:foreach="$emails as $email">
	      <td>{$suma = $suma + 1}</td>
	      <td>{$email->email}</td>
	      <td>{$email->name}</td>
	      <td>{$email->surename}</td>
	    </tr>
	  </tbody>
	</table>
	{/snippet}

porblém je v tom, že pokud vyberu nějaké záznamy, tak se mě medoda handleEmailDelete provede, ale snippet se mě již nepřekreslí a zůstanou v něm stejné udaje

Jan Endel
Člen | 1016
+
0
-

Překreslí, ale data v něm zůstanou stejná, protože render metoda, která ten snippet má naplnit se provede až po akci handle která ten snippet překresluje.

btw, stačí jenom $this->redrawControl(‚emailTable‘);, nemusíš to duplikovat.

CJHornster
Člen | 56
+
0
-

jj to mě taky napadlo, ale zase pokud dám v render metodě

if(!isset($this->template->emails)){$this->template->emails = $emails;}

tak mě v google-network vyhodí akce get error 500

Mysteria
Člen | 797
+
0
-

Prostě to přesuň do render metody:

if ($this->ajax) $this->redrawControl('emailTable');
Šaman
Člen | 2666
+
+1
-

Namísto handle použij action a mělo by to fungovat i bez přesouvání.

duke
Člen | 650
+
+1
-

Neměla by metoda handleEmailsDelete mazat ty emaily (tj. volat metodu delete)? Vidím tam jen get. Jinak by po zpracování signálu mělo následovat přesměrování pokud nejde o ajax (např. když má uživatel vypnutý javascript), takže bych do handle metody dal:

	if ($this->ajax) {
		$this->redrawControl('emailTable');
	} else {
		$this->redirect('this');
	}

Jinak by Tě mohlo zajímat, že místo:

	<td>{$suma = $suma + 1}</td>

… lze v Latte šablonách použít:

	<td>{$iterator->counter}</td>

A pak máš ještě překlep v „surename“. Příjmení je anglicky „surname“.

CJHornster
Člen | 56
+
0
-

jj na překlepy jsem mistr :D dík za

<td>{$iterator->counter}</td>

to se docela hodí
@Šaman jj zkusím to hodit do action

Zax
Člen | 370
+
0
-

Jan Endel napsal(a):

Překreslí, ale data v něm zůstanou stejná, protože render metoda, která ten snippet má naplnit se provede až po akci handle která ten snippet překresluje.

V tomhle bych problém nehledal, redrawControl (resp. zastaralé invalidateControl) nic nepřekreslí, jen označí snippet k překreslení a samotné překreslení si řeší až Latte.

Spíš jak říká @duke – nějak tam nevidím to mazání, jen natvrdo tahání jedné položky ->get(3); a vkládání do šablony, která pak zkouší procházet všechny záznamy. Nette\Database jsem dlouho nepoužíval, ale výsledkem volání ->get(3) asi nebude pole záznamů, které by šlo projít foreachem, nebo jo?

Spíš bych si přidal do Javascriptu rozšíření pro ajax, něco jako

$.nette.ext('consoleLog', {
    success: function(payload) {
        console.log(payload);
    },
    error: function(jqXHR, status, error) {
        console.log('FAIL!');
        console.log(error);
        console.log(jqXHR);
    }
});

a zkoumal, co přesně se vrací.

Editoval Zax (12. 8. 2014 14:08)

CJHornster
Člen | 56
+
0
-

mazání jsem tam neměl implementované, protože sem si nechtěl pořát promazávat a generovat záznami z DB (prostě lenost :D) tak sem se rozhod, že si místo všech záznamů vypíšu pouze jeden s ID 3 ;)

Zax
Člen | 370
+
0
-

Jo to je samozřejmě v pořádku, ale stejně si myslím, že nejde iterovat nad výsledkem metody get(). Ta, pokud se nepletu, vrací instanci jednoho řádku (ActiveRow), nikoliv Selection.

Co to zkusit obalit do array? ;-)

$this->template->emails = array($this->database->table('emails')->get(3));

EDIT: a nebo prostě použít where

// vrátí Selection s jedním záznamem
$this->template->emails = $this->database->table('emails')->where('id = ?', 3);

Editoval Zax (12. 8. 2014 16:13)