Komponenta na stránkování – pochopil jsem to správně?

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

Zdravím, jelikož jsem prozatím stránkování řešil přímým psaním kódu do Latte šablon, na což jsem nedávno doplatil, kdy jsem kvůli jedné úpravě musel měnit asi 30× ten samý kód, tak jsem se konečně rozhodl posunout s Nette dál a naučit se konečně pracovat s komponentama.

Podle různých návodů jsem vytvořil následující funkční kód, ale rád bych se zeptal, jestli je tohle správná cesta, abych to nemusel za půl roku přepisovat, protože jsem někde něco špatně pochopil.

Díky.

Definice komponenty a její vytvoření:

<?php namespace Components;
class PaginationControl extends \Nette\Application\UI\Control {
	public function render(array $where, array $order, array $limit, $pages, $pageLimit) {
		$this->template->setFile(__DIR__ . '/templates/pagination.latte');
		$this->template->where = $where;
		$this->template->order = $order;
		$this->template->limit = $limit;
		$this->template->pages = $pages;
		$this->template->pageLimit = $pageLimit;
		$this->template->render();
	}
}

interface IPaginationControlFactory {
	/** @return \Components\PaginationControl */
	function create();
}

Latte šablona komponenty:

<a class='ajax' href="{plink :{$presenter->name}:{$presenter->action} $where, $order, ['lim' => $limit['lim'], 'off' => 0]}">{_common.component.page.first}</a>
<a class="ajax{$i === ($limit['off'] + $limit['lim']) / $limit['lim'] ? ' current'}" href="{plink :{$presenter->name}:{$presenter->action} $where, $order, ['lim' => $limit['lim'], 'off' => ($i - 1) * $limit['lim']]}" n:for="$i = $limit['off'] / $limit['lim'] + 1 - $pageLimit <= 1 ? 1 : $limit['off'] / $limit['lim'] + 1 - $pageLimit; $i <= ($limit['off'] / $limit['lim'] + 1 + $pageLimit <= $pages ? $limit['off'] / $limit['lim'] + 1 + $pageLimit : $pages); $i++">{$i}</a>
<a class='ajax' href="{plink :{$presenter->name}:{$presenter->action} $where, $order, ['lim' => $limit['lim'], 'off' => ($pages - 1) * $limit['lim']]}">{_common.component.page.last}</a>

Vytvoření komponenty:

public function createComponentPagination(\Components\IPaginationControlFactory $factory) {
	return $factory->create();
}

Použití komponenty:

{control pagination $where, $order, $limit, $pages, $pageLimit}
Jan Endel
Člen | 1016
+
0
-

než vymýšlet dosti prasácké kolo, nechceš radši použít něco už fungujícího ?

Mysteria
Člen | 797
+
0
-

To právě nechci, protože bych rád i další věci předělal do komponent. A na to už existující věci nenajdu. Stránkování jsem zvolil jako příklad, protože ho používá asi každý. :)

Mě nejde o hodnocení třeba toho super jednořádkovýho foru pro vypisování jednotlivých položek před a za stránkou a podobný „nesmysli“. Mě šlo spíš o to, jestli je OK předávání parametrů v šabloně nebo jestli je lepší to předávat nějak už v presenteru (u toho jsem nenašel jak), jestli je OK dělat v šabloně controlu linky přímo na presenter místo na handle komponenty, tak jak to dělá třeba tebou zmíněné řešení (na které jsem samozřejmě taky narazil). Jak říkám, kdybych chtěl jenom vyřešit stránkování a tím skončit, tak to klidně použiju, ale o tohle mě nejde. :)

David Matějka
Moderator | 6445
+
+2
-

jestli je OK předávání parametrů v šabloně

ne – krom jinyho budes mit problem s ajaxem.

Jak predavat parametry do konstruktoru komponenty pres tovarnu najdes treba tady: http://www.zeminem.cz/…nitive-guide, pripadne muzes pouzit settery.

Ale nejdriv se koukni treba na to, co posila @JanEndel – konkretne jak si komponenta drzi aktualni stranku. Pak se koukni na persistentni parametry a nebudes muset predavat do ty komponenty skoro nic.

Mysteria
Člen | 797
+
0
-

@David Matějka: Díky za typy. Takže jsem to přepsal takto, funguje v pořádku jako to předchozí, ale tenhle kód se už i mě líbí víc.

Je to už lepší nebo jsem ještě něco minul?

Definice komponenty:

<?php namespace Components;
class PaginationControl extends \Nette\Application\UI\Control {
	/** @var integer */
	private $maximumPages;
	/** @var array */
	private $limit = [];

	public function __construct(array $limit, $maxPages) {
		list($this->limit, $this->maximumPages) = func_get_args();
	}

	public function render() {
		$this->template->setFile(__DIR__ . '/templates/pagination.latte');
		$this->template->limit = $this->limit;
		$this->template->pages = $this->maximumPages;
		$this->template->pageLimit = 10;
		$this->template->render();
	}

	public function handleChange(array $limit) {
		$this->presenter->redrawControl();
	}
}
interface IPaginationControlFactory {
	/** @return \Components\PaginationControl */
	function create(array $limit, $maxPages);
}

Šablona komponenty:

<a class='ajax' n:href="change! ['lim' => $limit['lim'], 'off' => 0]">{_common.component.page.first}</a>
<a class="ajax{$i === ($limit['off'] + $limit['lim']) / $limit['lim'] ? ' current'}" n:href="change! ['lim' => $limit['lim'], 'off' => ($i - 1) * $limit['lim']]" n:for="$i = $limit['off'] / $limit['lim'] + 1 - $pageLimit <= 1 ? 1 : $limit['off'] / $limit['lim'] + 1 - $pageLimit; $i <= ($limit['off'] / $limit['lim'] + 1 + $pageLimit <= $pages ? $limit['off'] / $limit['lim'] + 1 + $pageLimit : $pages); $i++">{$i}</a>
<a class='ajax' n:href="change! ['lim' => $limit['lim'], 'off' => ($pages - 1) * $limit['lim']]">{_common.component.page.last}</a>

Vytvoření komponenty:

public function createComponentPagination(\Components\IPaginationControlFactory $factory) {
	return $factory->create($this->limit, $this->maximumPages);
}

Vykreslení komponenty:

{control pagination}
Oli
Člen | 1215
+
0
-

Obecně málokde je nutné předávat si to šablonou. Typicky, pokud ty data nejsou, a jednoduše nemůžou být, známý už v presenteru/komponentě, tak se to předá až v šabloně. Jak velice jednoduse postavit znovupoužitelnou komponentu je třeba tady: https://forum.nette.org/…ura-projektu#…

Je výhoda (poslední dobou jsem tomu konečně přišel na chuť) pokud programuješ proti interface. potom v komponentě vyžaduješ právě to rozhraní. Pokud chceš komponentu pěkně znovupoužitelnou, což chceš vždycky, tak by měla vyžadovat minimum závislostí, které jí budou stačit k plnné činnosti.

David Matějka
Moderator | 6445
+
0
-

@Mysteria jeste presun ty vypocty pryc ze sablony, to tam nema co delat.