Přistupování do komponent v jiném stromu
- AlesMenzel
- Člen | 13
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ě?
- AlesMenzel
- Člen | 13
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)
- AlesMenzel
- Člen | 13
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.
- David Matějka
- Moderator | 6445
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
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)