getPresenter uvnitř Componenty
- MW
- Člen | 626
Zdravím, po letech refaktoruji aplikaci a trochu narážím. Mohu poprosit o radu? :)
Od presenteru:
public function createComponentGrid(): DataGrid {
return $this->userDataFactory->create();
}
GridFactory:
declare(strict_types=1);
namespace App\Grids;
use Nette;
use Ublaboo\DataGrid\DataGrid;
final class GridFactory
{
use Nette\SmartObject;
public function create(): DataGrid
{
return new DataGrid;
}
}
a nakonec
UserGridFactory:
final class UserGridFactory {
use Nette\SmartObject;
private GridFactory $factory;
private Explorer $database;
private UserManager $userManager;
public function __construct(GridFactory $factory, Explorer $database, UserManager $userManager) {
$this->factory = $factory;
$this->database = $database;
$this->userManager = $userManager;
}
public function create(): DataGrid {
$datagrid = $this->factory->create();
$datagrid->setDataSource($this->database->table('users'));
...
...
...
return $datagrid;
}
}
A problém je, že nefuguje $this->getPresenter() v UserGridFactory :
Call to undefined method App\Grids\UserGridFactory::getPresenter()
Přiznám se, že jsem to dříve ve factory řešil jen přes interface kde byla pouze create().. teď to zkouším podle posledního SandBoxu.. asi jen přehlížím nějakou dědičnost/předávání ??
Moc děkuji
Editoval MW (2. 3. 2021 21:43)
- Šaman
- Člen | 2667
Nevím, co se změnilo v posledním Sandboxu, ale
UserGridFactory
přece nic o žádném presenteru neví a existuje
nezávisle na něm. A nemá ani metodu getPresenter()
, je to
úplně obyčejná třída, která od ničeho nedědí.
Presenter získáš až tom vytvořeném UserGridu a to ne kvůli Factory, ale
protože ho vytvoříš v metodě presenteru createComponent…
.
Což zajistí, že se vytvořená komponenta (UserGrid
) připojí
do stromu komponent pod ten presenter a od té doby už o něm ví. (Jen je
presenter dostupný až PO konstruktoru – až po připojení hotové
komponenty do stromu.)
Dodatek: Když to tak čtu, tak jsem nezdůraznil, že Factory není komponenta. Je to továrna na komponentu. V komponentě už getPresenter fungovat bude.
P.S. Mimochodem v tom kódu neukazuješ použití toho
getPresenter
. Chyba bude asi v tom, protože továrna by presenter
typicy potřebovat neměla.
Editoval Šaman (3. 3. 2021 13:52)
- MW
- Člen | 626
Možná na tu jdu úplně špatně.
Toto je pro inlineAdd, jak by bylo vhodné to udělat lépe, prosím?
Díky moc!
$inlineAdd->onSubmit[] = function($values) {
try {
$this->userManager->add($values['username'], $values['email'], $values['password'], $values['role'], $values['group1'], $values['group2']);
} catch (\App\Model\DuplicateNameException $e) {
$this->getPresenter()->flashMessage('Uživatel existuje, záznam nebyl uložen!', 'danger');
$this->redirect('Users:');
}
$this->getPresenter()->flashMessage('Záznam přidán!', 'success');
$this->redirect('Users:');
};
- Šaman
- Člen | 2667
Navázat flashmessage až v presenteru. Dělám to tak u formulářů –
základní zpracování dat si zařídí formulář sám (u mě je formulář
vpodstatě součástí modelu), ale hlášky o ne/úspěšném zpracování a
nějaké další přesměrování si na onSuccess
(a
onError
) navěsí sám presenter (který jediný ví, kam
přesměrovat apod.)
// jsme v presenteru
protected function createComponentUserForm()
{
$form = $this->userFormFactory->create();
$form->onSuccess[] = function($values) {
$this->flashMessage('Záznam přidán!', 'success');
$this->redirect('Users:');
}
return $form;
}
Editoval Šaman (3. 3. 2021 16:34)