Proč signál vedoucí do konkretní komponenty spustí všechny createComponent metody daného presenteru?
- crassus
- Backer | 78
Ahoj,
mám FrontPresenter.php ve kterém jsou createComponent metody, např.
- createComponentProductListingControl()
- createComponentSearchPopupControl()
- atd..
Proč signál, který spouští handle v searchPopupControl, musí zároveň volat metodu createComponentProductListingControl() ?
Dá se tomu nějak zabránit?
Editoval crassus (24. 12. 2018 23:52)
- crassus
- Backer | 78
Předek je pouze ten FrontPresenter. Takže mě při ajaxovém requestu opravdu stačí, ať se vyrobí jenom 1 komponenta, do které vede ten ajaxový request. Je zbytečné, aby se vytvářely všechny ostatní komponenty (tahali se data z db), když se pak stejně nepoužijou.
CZechBoY napsal(a):
Protoze tvoje komponenta je zanorena… Jak bys ji chtel vytvorit bez vytvoreni predku?
- crassus
- Backer | 78
Okay tak tady je ten FrontPresenter.php. Proč se spouští createComponentProductListingControl() při ajaxovém requestu do handle metody v SearchPopupControl? Já při tom requestu vůbec ProductListingControl nepotřebuji.
FrontPresenter.php
<?php
namespace App\Presenters;
use App\Components\ProductListing\ProductListingControl;
use App\Components\ProductListing\IProductListingControlFactory;
use App\Components\SearchPopup\SearchPopupControl;
use App\Components\SearchPopup\ISearchPopupControlFactory;
final class FrontPresenter extends BasePresenter
{
/** @var IProductListingControlFactory */
private $productListingControlFactory;
/** @var ISearchPopupControlFactory */
private $searchPopupControlFactory;
/**
* @param IProductListingControlFactory $productListingControlFactory
* @param ISearchPopupControlFactory $searchPopupControlFactory
*/
public function __construct(IProductListingControlFactory $productListingControlFactory, ISearchPopupControlFactory $searchPopupControlFactory)
{
$this->productListingControlFactory = $productListingControlFactory;
$this->searchPopupControlFactory = $searchPopupControlFactory;
}
/**
* @return ProductListingControl
*/
public function createComponentProductListingControl()
{
return $this
->productListingControlFactory
->create();
}
/**
* @return SearchPopupControl
*/
public function createComponentSearchPopupControl()
{
return $this
->searchPopupControlFactory
->create();
}
}
Badaboom napsal(a):
Odpověď je ve tvém kódu, Nette ty komponenty samovolně nevytváří. Bez tvého kódu budeme všichni jen hádat.
Editoval crassus (25. 12. 2018 14:04)
- Badaboom
- Člen | 33
Nikde v tom kódu nevidím použití těch komponent, ale tak zkusím to :) Podle názvů budu předpokládat, že jsou to vykreslované komponenty. Takže někde v šabloně budeš mít
{control searchPopupControl}
{control productListingControl}
Když pošleš signál do SearchPopupControl
, tak program
nepřestane pracovat po vyhodnocení handle metody. Životní cyklus pokračuje
dál, takže se vykreslí i ta šablona a proto se ti vytvoří i
ProductListingControl
, viz životní cyklus presenteru.
- crassus
- Backer | 78
Chápu, ale já v té handle metodě volám: $this->redrawControl(‚nejakySnippetVKomponenteSearchPopupControl‘). Proč se teda renderují šablony dalších komponent? Když překresluji jenom nějaký fragment html kódu searchPopup komponenty?
Badaboom napsal(a):
Nikde v tom kódu nevidím použití těch komponent, ale tak zkusím to :) Podle názvů budu předpokládat, že jsou to vykreslované komponenty. Takže někde v šabloně budeš mít
{control searchPopupControl} {control productListingControl}
Když pošleš signál do
SearchPopupControl
, tak program nepřestane pracovat po vyhodnocení handle metody. Životní cyklus pokračuje dál, takže se vykreslí i ta šablona a proto se ti vytvoří iProductListingControl
, viz životní cyklus presenteru.
- Badaboom
- Člen | 33
Protože tím překreslením se životní cyklus presenteru neukončí. Nette neví, pokud mu to neřekneš, co se má v rámci toho requestu ještě stát. Ta handle metoda může třeba změnit nějaký state a na základě toho se má překreslit další komponenta. A další komponenty se vykreslí, protože prostě v rámci toho životního cyklu jsou vykreslovány.
Zkus na to nahlížet tak, jako by to nebyl ajax request, protože to na tom průchodu až tolik nemění. Pokud se ti komponenta vykreslí při běžném requestu, tak se ti vykreslí i při ajaxovém requestu (pokud to nemáš nějak ošetřené).
Kdybys opravdu chtěl, tak ten cyklus můžeš po vyhodnocení
SearchPopupControl::handleFoo()
stopnout, např.:
// SearchPopupControl:
use SmartObject;
public $onAjaxHandle = [];
public function handleFoo()
{
if ($this->presenter->isAjax()) {
$this->onAjaxHandle();
}
}
// FrontPresenter:
public function createComponentSearchPopupControl()
{
$control = $this->searchPopupControlFactory->create();
$control->onAjaxHandle[] = function () {
$this->terminate();
};
return $control;
}
Nebo můžeš chování upravit pomocí metody
Presenter::isSignalReceiver()
– pokud není komponenta
příjemcem signálu, tak ji nevykreslovat.
Ale pokud k tomu nemáš opravdu zásadní důvod, tak bych to nedoporučoval – ochudíš se o to dobré a zanese to trochu wtf do případného debugování.
Editoval Badaboom (25. 12. 2018 14:44)
- Badaboom
- Člen | 33
Nemáš ty komponenty obalené nějakým dalším snippetem, který také
překresluješ? Nesaháš na tu druhou komponentu v presenteru (nevím, jestli
ta ukázka je kompletní presenter) ? Protože po tom redrawControl
v komponentě opravdu nevidím moc jiných důvodů, aby se vytvářela ta
druhá komponenta.
Editoval Badaboom (25. 12. 2018 16:05)
- crassus
- Backer | 78
Máš pravdu, mě se tam v některých situacích nevolala redrawControl(), proto se spouštěly další komponenty. Pro dané situace volám v handle metodě: $this->getPresenter()->terminate() a funguje to suprovně.
Díky moc :)
Badaboom napsal(a):
Nemáš ty komponenty obalené nějakým dalším snippetem, který také překresluješ? Nesaháš na tu druhou komponentu v presenteru (nevím, jestli ta ukázka je kompletní presenter) ? Protože po tom
redrawControl
v komponentě opravdu nevidím moc jiných důvodů, aby se vytvářela ta druhá komponenta.