Přistupování do komponent v jiném stromu

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

Ahoj, učím se s Nette a zajímalo by mě, jak by jste řešili takovouto modelovou situaci (viz. obrázek – zdroj: gog.com). A chtěli by jste z komponenty filter, search nebo options ovlivnit komponentu výpisu (list). Teď k tomu přistupuji tak, že ve filterControl mám událost onFilter a tu propaguji skrz headerControl až do presenteru, kde už lze udělat následovné:

<?php
    $this["listControl"]->updateFilters();
?>

,ale problém tohoto způsobu je v nekonečném psaní událostí a pokud by těch zanořených komponent bylo více, tak tu samou událost bude třeba pro každou úroveň (eg. searchControl->onSearch(), poté headerControl->onSearch() a teprve v presenteru v továrně tento signál odchytnout a provést předchozí kód). Druhým způsobem, který mě napadl je odkazovat z událostí přímo na presenter, tím ale přicházíme o znovupoužitelnost, kvůli vazbě na presenter. Viz takto:

<?php
public function createComponentSearch() {
		$searchForm = $this->searchFormFactory->create();

		$searchForm->onSuccess[] = array($searchForm, "processSuccess");
		$searchForm->onSuccess[] = function(SearchForm $form) {
			$this->presenter["list"]->update();
		};

		return $searchForm;
	}
?>

Jak to řešíte vy, resp. jaká je best practice v tomto případě?

CZechBoY
Člen | 3608
+
0
-

Já se v komponente vypisu zeptam filtrovaci komponenty co mam filtrovat, strankovaci komponenty kolik toho zobrazit, sortovaci komponenty podle řadit.

AlesMenzel
Člen | 13
+
0
-

CZechBoY napsal(a):

Já se v komponente vypisu zeptam filtrovaci komponenty co mam filtrovat, strankovaci komponenty kolik toho zobrazit, sortovaci komponenty podle řadit.

Ale tím přicházíš o znovupoužitelnost té komponenty, protože tam najednou máš závislost mezi výpisem a filtrem. Resp. už nemůžeš mít výpis bez filtru.

Takže ty v té výpisové komponentě máš něco takového: ?

<?php
	$search = $this->presenter["header-search"]->getSearch();
	$filter = $this->presenter["header-filter"]->getFilter();
	$options = $this->presenter["header-options"]->getOptions();
?>

Editoval AlesMenzel (19. 12. 2015 22:33)

CZechBoY
Člen | 3608
+
0
-

Dělám si ty komponenty ve vypisovaci komponente. Presenter vytváří jen tu vypisovaci komponentu.
Ale vesměs je to stejné jak píšeš.

AlesMenzel
Člen | 13
+
0
-

CZechBoY napsal(a):

Dělám si ty komponenty ve vypisovaci komponente. Presenter vytváří jen tu vypisovaci komponentu.
Ale vesměs je to stejné jak píšeš.

A jak řešíš když chceš mít ty filtry zobrazene mimo tu vypisovou komponentu? Viz:

<?php
	{control filter}

	{control nějakáKomponentaMezi}

	{control výpis}
?>

Kdy nemůžeš mít výpis > filter.

CZechBoY
Člen | 3608
+
0
-

To jsem neřešil, protože vždycky když vypisuju filtry tak se vážou na nějakej výpis.

Co to je za filtry?

David Matějka
Moderator | 6445
+
0
-

Ja to resim na nekterych mistech tak (kdyz to zjednodusim), ze ty filtrovaci komponenty implementuji interface, nejaky IFilterProvider treba, s metodou getFilters(). Ta vraci bud nejaky criteria objekty nebo specification objekty. A projdu vsechny tyhle komponenty pres getComponents a vezmu si z nich filtry

AlesMenzel
Člen | 13
+
0
-

David Matějka napsal(a):

Ja to resim na nekterych mistech tak (kdyz to zjednodusim), ze ty filtrovaci komponenty implementuji interface, nejaky IFilterProvider treba, s metodou getFilters(). Ta vraci bud nejaky criteria objekty nebo specification objekty. A projdu vsechny tyhle komponenty pres getComponents a vezmu si z nich filtry

@DavidMatějka Takže v kódu k tomu přistupuješ asi takhle?

<?php
foreach($this->presenter->getComponents($deep = true, $type = "FilterControl") as $component) {
	if($component->getName() === "filter") {
		$this->setFilters($component->getCrierias()); // nebo getFilters(); // $this je v tomto případě výpis //
		return true; // filtrační komponenta existuje
	}
}
return false; // filtrační komponenta není
?>

Což by se dalo zapsat lépe asi takhle (pokud víme kde ta komponenta je):

<?php
	try {
		$this->setFilters($this->presenter["x-y-z-filter"]->getCriterias());
	} catch (Exception $ex) {
		// filtrační komponenta není
	}
?>

S tím že ty objekty „kriterií“, či „specifikací“ obsahují pole podle čeho filtrovat.

<?php
[
	"authors" => ["John", "Frank", "Maria"]
	"date_posted" => ...
]
?>

Editoval AlesMenzel (21. 12. 2015 20:43)