Zachování persistentních parametrů komponenty při volání signálu z šablony presenteru

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

Snažím se teď rozběhnout jednu komponentu, jejíž persistentní parametry by se měly měnit pomocí jejích signálů, ale ty se mají volat až z šablony presenteru. Problém je ale v tom, že komponenta má parametrů více a pokud měním vždy jen jeden z nich, v tu chvíli se mi vrací ty ostatní vynulované (null). Co dělám špatně?

(Nebo je koncept volání z šablony presentru úplně lichý? Vím, že by bylo lepší mít to volání signálů přímo v šabloně komponenty (tam mi to funguje, btw), ale konkrétní situace v projektu moc neumožňuje to takto udělat.)

Komponenta:

<?php

/** @persistent int */
public $a = 0;

/** @persistent int */
public $b = 0;

public function handleChangeValues ($a, $b) {
	if(isset($a)) {$this->a = $a;}
	if(isset($b)) {$this->b = $b;}
}

?>

Šablona presenteru:

<?php

<a n:href="komponenta:changeValues!, a => 1" class="ajax">Změň A</a>
<a n:href="komponenta:changeValues!, b => 1" class="ajax">Změň B</a>

?>
Oli
Člen | 1215
+
0
-

Nejsem si jistý, jestli to na to má vliv, ale myslím, že se ty signály volají takhle

<a n:href="komponenta-changeValues!, a => 1" class="ajax">Změň A</a>
<a n:href="komponenta-changeValues!, b => 1" class="ajax">Změň B</a>
koren
Člen | 59
+
0
-

Podle toho co jsem zkoušel, tak funguje jak podrtžítková, tak dvojtečková notace. Minimálně tedy v příkladu Fifteen je použitá ta dvojtečková a šlape to. Problém bude někde jinde…

trejjam
Backer | 65
+
0
-

Parametry komponenty by měli mít prefix jako komponenta samotná, zkus něco takového:

<a n:href="komponenta-changeValues!, komponenta-a => 1" class="ajax">Změň A</a>
<a n:href="komponenta-changeValues!, komponentaA => 1" class="ajax">Změň A</a> //nevím která varianta bude OK

Nejjednodušší zjištění by mělo být zavolání z komponenty:

	dump($this->link('changeValues!', ['a' => 1])); //vypíš link (na komponentu), z kterého už vše poznáš
Zax
Člen | 370
+
0
-
  1. Dvojtečková notace mě osobně překvapila, takže jsem se musel přesvědčit sám a ono to tak v příkladu Fifteen opravdu je! Vůbec jsem netušil, že tohle může fungovat, dvojtečková notace se obvykle používá pro zápis Presenter:action, o formátu komponenta:signál slyším fakt poprvé.
  2. Jak píše @trejjam, cesta i parametry musí být prefixované celou cestou ke komponentě, tzn persistentní parametr abc v komponentě foo má celý název foo-abc. Naprosto stejně to ale funguje i se signály a parametry signálu. Nejsem si přesně jistý, co se děje v momentě kdy voláš signál s parametrem, jehož název (včetně cesty) je totožný s názvem persistentního parametru, této situaci se osobně vyhýbám a tipnul bych, že v tom možná bude ten problém. Zkusil bych přejmenovat parametry v signálu na něco jiného.

Editoval Zax (18. 10. 2015 10:03)

koren
Člen | 59
+
0
-

Díky všem za rady, ale bohužel se tím nic nezměnilo :/ Upravil jsem kód následovně, ale pořád se děje to, že opětovným voláním signálu se vždy změní jen ta posledně měněná proměnná, ale ta druhá se nulluje.

Komponenta:

<?php

/** @persistent int */
public $a = 0;

/** @persistent int */
public $b = 0;

public function handleChangeValues ($newA, $newB) {
	if(isset($newA)) {$this->a = $newA;}
	if(isset($newB)) {$this->b = $newB;}
}

?>

Šablona presenteru:

<a n:href="komponenta-changeValues!, komponenta-newA => 1" class="ajax">Změň A</a>
<a n:href="komponenta-changeValues!, komponenta-newB => 1" class="ajax">Změň B</a>

Při prvním kliku na první odkaz mi to správně vrátí:

{"state":{"komponenta-a":"1","komponenta-b":null},"snippets":{"snippet-komponenta-":""}}.

Při následnem kliku na druhý odkaz mi to ale už vrátí:

{"state":{"komponenta-a":null,"komponenta-b":"1"},"snippets":{"snippet-komponenta-":""}}

Přijde mi tedy, že problém není ani tak v tom volání signálu (protože to funguje), ale spíš v tom, že ty parametry se prostě nechovají persistentně. Vlastně mi ani nezůstávájí v URL, (což bych čekal, když mají po změně jinou než defaultní hodnotu + mám v komponentě funkce loadState a saveState včetně volání jejich rodičů). Čím by o mohlo být?

F.Vesely
Člen | 369
+
0
-

Tohle reseni, kdy spolehas na nejake zanoreni komponenty a z toho odvozujes tu cestu, se mi moc nezda. Nebylo by lepsi si udelat metodu renderChangeLink($a, $b) a nechat vytvoreni odkazu na te komponente?

hitzoR
Člen | 51
+
0
-

Kontrola isset() je špatná, protože ony ty parametry funkce existujou vždycky (když už ti teda to volání projde, což podle mě není úplně správné chování, protože máš nastavený jen jeden parametr). Správně bys měl kontrolovat, zda není proměnná null

public function handleChangeValues ($newA, $newB) {
    if(!is_null($newA)) {$this->a = $newA;}
    if(!is_null($newB)) {$this->b = $newB;}
}
David Matějka
Moderator | 6445
+
0
-

@hitzoR http://cz2.php.net/…on.isset.php

Determine if a variable is set and is not NULL

hitzoR
Člen | 51
+
0
-

Sakra, a já měl za to, že pokud ta proměnná má hodnotu null, tak je „set“. Každopádně pak to chování nechápu (už divné je to, že projde volání handleru se zadáním jen jednoho parametru, když ten druhý nemá defaultní hodnotu), ale minimálně bych to !is_null vyzkoušel.

Ale i tak mi přijde tohle zvláštně řešené a nenapadlo by mě to něco takhle řešit. A když už , tak buď si udělat dvě metody (pro A i B zvlášť) nebo si předat parametry do šablony a do linku doplnit i ten druhý.

RePRO
Člen | 32
+
0
-

hitzoR napsal(a):

Sakra, a já měl za to, že pokud ta proměnná má hodnotu null, tak je „set“. Každopádně pak to chování nechápu (už divné je to, že projde volání handleru se zadáním jen jednoho parametru, když ten druhý nemá defaultní hodnotu), ale minimálně bych to !is_null vyzkoušel.

Ale i tak mi přijde tohle zvláštně řešené a nenapadlo by mě to něco takhle řešit. A když už , tak buď si udělat dvě metody (pro A i B zvlášť) nebo si předat parametry do šablony a do linku doplnit i ten druhý.

Asi sis to spletl s tímto. :-)

<?php
   isset(null)  // false
   isset(false) // true
?>