getPresenter uvnitř Componenty

MW
Člen | 615
+
0
-

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 | 2635
+
0
-

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)

nightfish
Člen | 472
+
0
-

MW napsal(a):
A problém je, že nefuguje $this->getPresenter() v UserGridFactory :

K čemu Presenter v UserGridFactory potřebuješ/používáš?

MW
Člen | 615
+
0
-

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 | 2635
+
+4
-

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)

MW
Člen | 615
+
0
-

Super, moc díky!