jak dostat parametr do komponety

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

Ahoj.

Opět jsem se ztratil na mojí cestě k proniknutí do Nette a prosím o radu.

Zkouším dělat komponentu košík. V basePresenteru jsem si vytvořil componentu, která dostane přístup k db a sessions. V šabloně se mi zobrazujete prostě jako box, který ukazuje položky v košíku, jejich počet a podobně. To mi funguje. Přidání do košíku jsem řešil odkazem do presenteru a úpravou sessions.

Teď bych to chtěl předělat, abych byl button na přidání zboží taky součástí té komponenty. Tak jsem si v té hlavní komponentě udělal další komponentu add s vlastní šablonou a v šabloně presenteru ten button vykresluji pomoci {control basket-add}. Nevím ale jak teď do té komponenty dostat id zboží, které se má přidat.

Díky

Martin

Šaman
Člen | 2666
+
0
-

Do komponenty můžeš dostat nějaká data/služby vpodstatě třemi způsoby.

  1. OŠKLIVĚ! Šáhneš si do $this->presenter->context. Ale je to špinavé. Když v kontextu nebude, co hledáš, tak komponenta nebude fungovat.
  2. Předáš nějaká data render metodě. To je sice jednoduché, ale zase s těmi daty nemůžeš pracovat dřív, než při renderování. V tomto případě nevhodné (ale jindy se to může hodit).
  3. Nejlepší způsob je předání všech závislostí a dat při vytváření komponenty (konstruktorem), nebo ihned po jejím vytvoření pomocí setteru. Tedy v továrničce něco jako:
<?php
protected function createComponentMyBasket()
{
	$basket = new MyBasketControl;
	$basket->addItem($itemId);
	return $basket;
}
?>
David Matějka
Moderator | 6445
+
0
-

doporucuju oddedil vizualni cast od logiky. udelej si tridu, treba ShoppingCart s metodami addItem, removeItem, getItems apod. tahle trida bude pracovat se session, db… a tuhle tridu registruj jako sluzbu

a soucasnou komponentu, ktera vykresluje box s polozkama predelej, ze nebude vyzadovat ani session, db .. jen onu ShoppingCart sluzbu.

pridani polozky do kosiku z nejakyho presenteru (treba z vypisu nebo z detailu) pak neresit pres komponentu, ktera vykresluje box, ale primo pres sluzbu ShoppingCart, na ktery se bude volat addItem metoda z nejakyho signalu (handle*) presenteru. kdyz se ti to nebude libit, tak si muzes udelat samostatnou komponentu, ktera se bude starat o pridani komponenty do kosiku.

kejlicz
Člen | 201
+
0
-

Díky za pomoc.

pro matej21 : Určitě si vyzkouším i Tvoje řešení. Zatím nic nevyvíjím a jen se učím, jak vlastně konponenty pracují a co se s nima dá dělat, proto nepřemýšlím moc nad návrhem.

pro Šamana : Zkoušel jsem tvoje řešení a mám dotaz. Mám továrničku na tu hlavní komponentu v BasePresenteru. Když ten parametr itemId získám takhle

$control->setItemId($this->getParameter("id"));

je to v pořádku, nebo je to taky prasečina?

Šaman
Člen | 2666
+
0
-

No, presentery jsou trochu mimo kasickou teorii o předávání závislostí a o provázání objektů. Samozřejmě existuje třída, která vytváří ostatní, předává jim závislosti a parametry a sama si je musí někde načíst (v Nette je to DI kontejner). A presenter k ní má hodně blízko. U komponenty je žádoucí, aby měla jasně definované api a závislosti, pak je znovupoužitelná i v jiném presenteru, nebo i v jiném projektu. Ale u presenteru tuto znovupoužitelnost a jasnou závislost nemá cenu moc řešit. Obecně, pokud nedovádíš DI do extrému – model a komponenty by měly být nezávislé na kontejneru (vše jim předá presenter), presenter si ale klidně může načítat parametry, nebo i služby (i když tam je lepší použít inject anotaci, nebo metodu). Nenarazíš s tím na žádný problém.

Pokud bys to chtěl extrémně čisté, tak myslím, že v novém Nette je možné nechat si presentery konfigurovat také v DI kontejneru a předání toho parametru ‚id‘ by se popsalo v configu.
Ale pokud si budeš parametry načítat přes getParameters(), tak neuděláš žádnou velkou chybu v návrhu.

Jan Suchánek
Člen | 404
+
0
-

@Šaman: Tzn.: používat $paginator = $this[„vp“]->getPaginator() není best way?

Edit: Nebo komponenta pro stránkování $this[„vp“] by mělá mít i pro svůj
život vytvořenou servisku \Nette\Utils\Paginator?

Editoval jenicek (5. 12. 2013 23:25)

Šaman
Člen | 2666
+
0
-

Myslím, že komponenta, která potřebuje stránkovat, by si měla vytvořit paginátor jako komponentu. U paginátoru by mělo stačit předat aktuální stránku té metodě render.
Ale poslední dobou jsem s paginátorem nic nedělal, takže nevím, jestli konkrétně na něj nejsou nějaké zkratky.

kejlicz
Člen | 201
+
0
-

Díky moc za obsáhlý rozbor. Momentálně jsem ve fázi učení a jsem rád, když něco funguje, takže to že to je normálně použitelné mi stačí.

Jan Suchánek
Člen | 404
+
0
-

@Šaman: Šlo mi o to kdy používat v komponentě něco podobného jako:

/**
 * @return Nette\Paginator
 */
public function getPaginator() {
    if (!$this->paginator) {
        $this->paginator = new Paginator;
    }
    return $this->paginator;
}

nebo je lepší objekt \Nette\Utils\Paginator předávat komponentě jako service?

Zajímá mě názor, protože podobný styl použiju u své komponenty která bude řešit navigaci.

A je rozumné do presenteru vytahovat modely komponent?

Editoval jenicek (6. 12. 2013 0:17)