Předávání parametrů mezi komponentami a zpracování přes AJAX
- Danny
- Člen | 146
Zdravím,
měl bych jednu otázku jak řešíte např situaci kdy máte 2 komponenty a
potřebujete mezi nimi po zpracování formu ajaxem předávat informace a
překreslovat jejich snippety.
Řeším situaci kdy mám například komponentu která řeší vytvoření nějakého záznamu a obsahuje selectbox s výběrem uživatele a další inputy, pak mám druhou komponentu která řeší vytváření uživatele, oboje komponenty jsou injectnute v jednom presenteru a použity v jedné šabloně. Oboje komponenty jsou vidět na stránce a potřebuji docílit toho že pokud vytvořím uživatele na té stránce tak rovnou obnovit snippet komponenty pro vytvoření záznamu a nasetovat do selectboxu toho nového uživatele a zároveň neovlivnit to co uživatel při tvorbě vyplnil(další inputy).
Je vhodné řešení to řešit přes session nebo nějak jinak?
Děkuji za informace :-)
- Danny
- Člen | 146
Zkusím to lépe specifikovat. Mám Presenter kde si injectuju 2 komponenty přidání záznamu a přidání klienta.
class SheetPresenter extends BasePresenter
{
/** @var IAddCustomerComponent @inject */
public $IAddCustomerComponent;
/** @var IAddSheetComponent @inject */
public $IAddSheetComponent;
protected function createComponentCustomerComponent() {
$component = $this->IAddCustomerComponent->create();
$component->onSuccess[] = function($customer) {
$this->customer = $customer;
};
return $component;
}
protected function createComponentSheetComponent() {
$component = $this->IAddSheetComponent->create();
if($this->customer instanceof Customer) {
$component->setCustomer($this->customer);
}
return $component;
}
}
Dostal jsem se do stavu kdy si pomocí eventů předám ze zpracování(vytvoření klienta) konkrétní entitu klienta a nasetuju si jí do SheetComponenty.
class AddSheetComponent extends BaseComponent {
/** @var CustomerDao */
private $customerDao;
public function __construct(CustomerDao $customerDao)
{
parent::__construct();
$this->customerDao = $customerDao;
}
public function createComponentForm() {
$form = $this->create();
$form->addSelect('customer_id', 'klient', [vyber klientu]));
$form->addText('name', 'Name');
return $form;
}
public function setCustomer(Customer $customer) {
$this['form']['customer_id']->setDefaultValue($customer->getId());
}
}
interface IAddSheetComponent {
/** @return AddSheetComponent */
public function create();
}
Problém mi nastává v momentě kdy uživatel bude mít vyplněné něco v text inputu(name) a až poté začne vytvářet klienta, proces se provede ajaxem na pozadí a obnoví snippet, klient ID se načte do formu, ale všechny ostatní data zmizí protože se nijak nepřenaší a ta komponenta se vytváří znova. Je nějaká možnost jak to udělat aby se obnovil například pouze snippet uvnitř toho formuláře, tedy pouze customer_id ? Nějak nejsem schopný se dostat přes ten cyklus.
Děkuji
Editoval Danny (17. 12. 2019 12:16)
- Danny
- Člen | 146
Dám to sem celé. AddSheetComponent vytváří nějaký záznam, ten onSuccess je u vytváření klienta abych tu vytvořenou entitu mohl přenést do SheetComponenty. Tedy
class AddCustomerComponent extends BaseComponent {
public $onSuccess = [];
public function createComponentForm() {
$form = $this->create();
// inputy ...
$form->onSuccess[] = function (Form $form, \stdClass $values) {
$customer = new Customer()
$customer->setId(1);
....
// vytvoreni customera
$this->onSuccess($customer); // volání callbacku
// tady se snažím dělat redraw ale překresluji to pouze v presentru, protože nevím jak bych sáhnul do
druhé komponenty odtud
if($this->getPresenter()->isAjax()) {
$this->getPresenter()->redrawControl('sheet');
}
return $form;
};
return $form;
}
public function render() {
$template = $this->template;
$template->setFile(__DIR__ . '/component.latte');
$template->render();
}
}
interface IAddCustomerComponent {
/** @return AddCustomerComponent */
public function create();
}
šablona Sheet presentru
{block content}
{snippet sheet}
<div class="panel-body">
{control sheetComponent}
</div>
{/snippet}
<div class="panel-body">
{control customerComponent}
</div>
{/block}
- Danny
- Člen | 146
Nevim jestli si úplně rozumíme, potřebuju po vytvoření klienta nasetovat ty informace do jiné komponenty (což mám) a zároveň potřebuju v té druhé komponentě obnovit snippet a zároveň zachovat data které tam jsou, respektive tedy refreshnout jenom jeden input.
Bude to vůbec fungovat? Protože ty informace o klientovi setuji při vytváření té komponenty, tudíž tam naopak nebudu zase moci dostat data ne?
Editoval Danny (17. 12. 2019 17:09)
- Danny
- Člen | 146
Po pár dnech mi došlo že se snažím vymýšlet složitě něco co je poměrně jednoduché. Nakonec vyřešeno takhle
SheetPresenter.php
protected function createComponentCustomerComponent() {
$component = $this->IAddCustomerComponent->create();
$component->onSuccess[] = function($customer) {
if($customer instanceof Customer) {
if($this->isAjax()) {
/** @var AddSheetComponent $component */
$component = $this['addSheetComponent'];
$component->setCustomer($customer);
$component->redrawControl();
}
}
};
return $component;
}
protected function createComponentAddSheetComponent() {
$component = $this->IAddSheetComponent->create();
return $component;
}
- CZechBoY
- Člen | 3608
Do toho onSuccess
callbacku bych si dal typehint a potom už
necheckoval jestli je teda ten parametr typehint.
Továrnu bych pojmenoval se suffixem Factory – tzn.
IAddSheetComponentFactory
a
IAddCustomerComponentFactory
.
A když na to dojde tak proč event pojmenovávat onSuccess
když
můžeš mít třeba onCustomerAdded
.