Jak nejlépe vložit identifikátor do komponenty mající vlastní model

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

Mám komponentu pro detail článku. Součástí zodpovědnosti této komponenty je i získání objektu dotyčného článku. Zvenčí dostane jen identifikátor.

Otázka je, jakým způsobem do této komponenty vložit ten identifikátor. Uvažuji o dvou způsobech, každý má nějaké mouchy: buď mu to řeknu přes konstruktor, nebo mu to řeknu přes render().

Když to budu dělat přes konstruktor, tak nevím jak vhodně použít továrničku:

function createComponentDetail()
{
	return new DetailComponent($this->params['id']);
}

function actionDetail($id) {
	// zbytečná akce
}

V tomto případě vytvářím action jen kůli routeru. A identifikátor získávám v továrničce tak nějak podezřele. Ale nevím, třeba mi to vysvětlíte.

function actionDetail($id) {
	$this['detail'] = $this->articleControlFactory->create($id);
}

Tohle se zase nelíbilo jednomu mému kolegovi. Že je to nestandardní.

Způsob skrzeva render($id) ještě nemám prozkoumaný.

Cílem je, nedělat to takto:

function createComponentDetail()
{
	return new DetailComponent();
}

function actionDetail($id) {
	$this['detail']->id = $id;
}

Protože detail bez identifikátoru nemá smysl.

Díky moc za všechny postřehy.

David Matějka
Moderator | 6445
+
+2
-

rozhodne je nejlepsi to predavat pres konstruktor – ja osobne tedy nepredavam ID, ale celou entitu, kterou vytahnu prave v action

pres render to nedelej, bude to zpusobovat problemy napriklad se snippety (mluvil jsem o tom vcera na posobote)

Taco
Člen | 50
+
0
-

David Matějka napsal(a):

rozhodne je nejlepsi to predavat pres konstruktor – ja osobne tedy nepredavam ID, ale celou entitu, kterou vytahnu prave v action

OK. Předávat celou entitu, minimálně v tomto případě, nechci. Rád bych zkusil, zda by mohli být komponenty zcela autonomní.

Jaký způsob toho předání by si tedy zvolil? První, druhý? Nebo tě napadá ještě jiný?

David Matějka
Moderator | 6445
+
0
-

jsem to precetl moc rychle, takze jsem minul nektere body otezky :) v createComponent* pouzijes tu tovarnicku, ktera ten parametr preda do konstruktoru

takze

function createComponentDetail()
{
    return $this->articleControlFactory->create($this->getParameter('id'));
}
Taco
Člen | 50
+
0
-

David Matějka napsal(a):

jsem to precetl moc rychle, takze jsem minul nektere body otezky :) v createComponent* pouzijes tu tovarnicku, ktera ten parametr preda do konstruktoru

takze

function createComponentDetail()
{
    return $this->articleControlFactory->create($this->getParameter('id'));
}

OK, a mé námitky?

Že kůli routeru musím vytvářet prázdnou action, a že je tam ten id poněkud schován?

David Matějka
Moderator | 6445
+
0
-

V tomto případě vytvářím action jen kůli routeru.

jestli myslis {link detail $id}, tak muzes parametr pojmenovat ({link detail id => $id}).. ale obcas taky vytvarim prazdne action (hlavne kvuli castecne-persistentnim parametrum)

A identifikátor získávám v továrničce tak nějak podezřele

volani getParameter je ok. ale nic ti nebrani si v action id ulozit do clenske promenne :)

ale stejne prijdes na to, ze je lepsi predavat entitu :)

treba uz jen kvuli tomu, ze pokud neexistuje clanek, tak v komponente je pozde vracet 404. a autonomnost komponent to nijak nesnizuje

Taco
Člen | 50
+
0
-

David Matějka napsal(a):

V tomto případě vytvářím action jen kůli routeru.

jestli myslis {link detail $id}, tak muzes parametr pojmenovat ({link detail id => $id}).. ale obcas taky vytvarim prazdne action (hlavne kvuli castecne-persistentnim parametrum)

A identifikátor získávám v továrničce tak nějak podezřele

volani getParameter je ok. ale nic ti nebrani si v action id ulozit do clenske promenne :)

ale stejne prijdes na to, ze je lepsi predavat entitu :)

treba uz jen kvuli tomu, ze pokud neexistuje clanek, tak v komponente je pozde vracet 404. a autonomnost komponent to nijak nesnizuje

Díky za odpovědi.

Taco
Člen | 50
+
0
-

David Matějka napsal(a):

V tomto případě vytvářím action jen kůli routeru.

jestli myslis {link detail $id}, tak muzes parametr pojmenovat ({link detail id => $id}).. ale obcas taky vytvarim prazdne action (hlavne kvuli castecne-persistentnim parametrum)

A identifikátor získávám v továrničce tak nějak podezřele

volani getParameter je ok. ale nic ti nebrani si v action id ulozit do clenske promenne :)

To si ale moc nepomůžu. Výhodu továrniček považuji v tom, že se vytvářejí lazy, a presenter mám jako schránku na akce. Takže v jedné akci továrničku mohu použít, a v druhé nikoliv.

ale stejne prijdes na to, ze je lepsi predavat entitu :)

To je sice možné, ale vůbec to neřeší problém :-P


Zatím se mi nejvíc čisté zdá:

function actionDetail($id) {
    $this['detail'] = $this->articleControlFactory->create($id);
}

V čem je to špatné? Na jaké potíže mohu narazit?

Díky moc za odpovědi.

h4kuna
Backer | 740
+
+2
-

Přijde mi zbytečné tvořit komponentu, když ještě ani nevíš zda ji vykreslíš.

Udělal bych si vlastnost v rámci presenteru a tu nasetoval v action kde to potřebuješ. Tím nebudeš mít prázdnou action, továrnička bude lazy a předáš si id jako parametr.

Kolik těch Action bude jedna, dvě? Pokud jich bude více tak se zamyslet nad rozvržením presenteru zda použít persistentní parametr a co mu nevyhovuje přesunout do jiného presenteru.

Viz co píše @DavidMatějka

<?php

private $articleId;

function actionDetail($id) {
    $this->articleId = $id;
}

function actionFoo($barId) {
	$this->articleId = $barId;
}


function createComponentDetail()
{
    return $this->articleControlFactory->create($this->articleId);
}
?>

Editoval h4kuna (7. 6. 2016 14:31)

Taco
Člen | 50
+
0
-

h4kuna napsal(a):

Přijde mi zbytečné tvořit komponentu, když ještě ani nevíš zda ji vykreslíš.

Udělal bych si vlastnost v rámci presenteru a tu nasetoval v action kde to potřebuješ. Tím nebudeš mít prázdnou action, továrnička bude lazy a předáš si id jako parametr.

Kolik těch Action bude jedna, dvě? Pokud jich bude více tak se zamyslet nad rozvržením presenteru zda použít persistentní parametr a co mu nevyhovuje přesunout do jiného presenteru.

<?php

private $articleId;

function actionDetail($id) {
    $this->articleId = $id;
}

function actionFoo($barId) {
	$this->articleId = $barId;
}


function createComponentDetail()
{
    return $this->articleControlFactory->create($this->articleId);
}
?>

Děkuji za odpověď. Toto je asi nejblíž, tomu, jak bych to chtěl dělat (nutno poznamenat, že to David Matějka taky mezi řečí zmiňoval).

V tomto případě je kladena nutnost na to, dobře navrhnout presenter. Nelze to tam „jen hodit“, jak funguje praxe.

Připomělo mi to RESTové rozdělení:
ArticlesPresenter::actionDefault()
ArticlesPresenter::actionCreate()
ArticlePresenter::actionDetail($id)
ArticlePresenter::actionEdit($id)
ArticlePresenter::actionDelete($id)

newPOPE
Člen | 648
+
0
-

@Taco a teraz si porovnaj tie dva sposoby co tu spominate.

  1. pouzijes ten posledny s private property. Sice nemas prazde actions/renders ale zas mas viac magie
  2. pouzijes prazdne actions. Mas sice prazdne actions ale vies aku Presenter funkcionalitu.

Teraz sa treba zamyslet ako napr. budes potom hladat po kode ked budes chciet zistit ci mozes nejaku action/render metodu zmazat…

Co sa tyka predavania entity vs id tu treba brat v uvahu, ze komponenta (so sablonami a vlastnym modelom) je v ramci UI vrstvy cize ten dany model nie je model celej aplikacie tym padom mas lepsie tam predat Entitu.

Editoval newPOPE (7. 6. 2016 13:43)

h4kuna
Backer | 740
+
0
-

Taco napsal(a):
Děkuji za odpověď. Toto je asi nejblíž, tomu, jak bych to chtěl dělat (nutno poznamenat, že to David Matějka taky mezi řečí zmiňoval).

Jop, jen nebylo jasné pochopení z vašeho rozhovoru. A chtěl jsem podpořit tuto variantu :)

Taco
Člen | 50
+
0
-

newPOPE napsal(a):

@Taco a teraz si porovnaj tie dva sposoby co tu spominate.

  1. pouzijes ten posledny s private property. Sice nemas prazde actions/renders ale zas mas viac magie
  2. pouzijes prazdne actions. Mas sice prazdne actions ale vies aku Presenter funkcionalitu.

Teraz sa treba zamyslet ako napr. budes potom hladat po kode ked budes chciet zistit ci mozes nejaku action/render metodu zmazat…

V tom případě mi určitě přijde ta property čitelnější. Závislost je přímočará. Komponenta závisí na this->props, props závisí na akci. Akce vyžaduje argument. IMHO čisté.

Jen se musí zajistit, aby ta property vždy nesla stejnou hodnotu a nereciklovala se.

Co sa tyka predavania entity vs id tu treba brat v uvahu, ze komponenta (so sablonami a vlastnym modelom) je v ramci UI vrstvy cize ten dany model nie je model celej aplikacie tym padom mas lepsie tam predat Entitu.

OK, ale toto neřeší problém.