Přístup k modelu z továrny na formuláře
- Milan Obrtlík
- Člen | 50
Dobrý den,
jaký je podle vás nejlepší způsob přístupu k modelu (manageru)
z továrny na formuláře?
Nyní si třeba v app/forms/AdminFormFactory.php přidám kód:
/** @var \App\Model\ProductManager @inject */
public $productManager;
public function __construct(\App\Model\ProductManager $productManager) {
$this->productManager = $productManager;
}
a po odeslání formuláře „přidej produkt“:
$this->productManager->add($values);
Toto řešení mi připadne trochu těžkopádné, hlavně když mám ještě
categoriesManager, imagesManager, imagesStorage atd… To se mi pak __construct
nevleze na „Full HD“ řádek.
Existuje lepší způsob nebo jsem úplně mimo?
- Milan Obrtlík
- Člen | 50
newbie napsal(a):
Já bych to všechno schoval do fasády třeba ProductFacade a tam bych se až staral o jednotlivé Managery.
Omlouvám se, netuším co jsou tofasády. Můžete mi sem hodit relevantní odkazy k nastudování této problematiky?
Tomáš Votruba napsal(a):
Dobry den, jak vypada cely kod formulare?
Mozna to jde resit lepe.
namespace App\Forms;
use Nette;
use Nette\Application\UI\Form;
use Nette\Utils\Random;
class AdminFormFactory extends Nette\Object {
/** @var \App\Model\ProductManager @inject */
public $productManager;
/** @var \App\Model\CategoryManager @inject */
public $categoryManager;
/** @var \App\Model\ImageManager @inject */
public $imageManager;
/** @var ImageStorage @inject */
private $imageStorage;
public function __construct(\App\Model\ProductManager $productManager, \App\Model\CategoryManager $categoryManager, \ImageStorage $imageStorage, \App\Model\ImageManager $imageManager) {
$this->productManager = $productManager;
$this->categoryManager = $categoryManager;
$this->imageManager = $imageManager;
$this->imageStorage = $imageStorage;
}
public function createAddSubcategoryForm() {
$form = new Form;
$form->addText('name');
$form->addText('id');
$form->addSubmit('send');
$form->onSuccess[] = [$this, "formAddSubcategorySucceeded"];
return $form;
}
public function formAddSubcategorySucceeded(Form $form, $values) {
$this->categoryManager->newChildOfCategory($values->id, $values->name);
}
}
Zbylé formuláře jsou téměř totožné, teda až na formulářové prvky.
- Tomáš Votruba
- Moderator | 1114
@MilanObrtlík Díky.
Vypadá to, že v této třídě potřebuješ jen
$this->categoryManager
. Tedy jak píše @DavidMatějka ,
vytvoř si 4 samostatné třídy. Co formulář, to samostatná
továrnička.
- Anotace
@inject
můžeš odstranit, jelikož už používáš constructor. - Dědit od
Nette\Object
také není potřeba.
Editoval Tomáš Votruba (11. 9. 2015 11:44)
- Milan Obrtlík
- Člen | 50
Myslím, že továrna pro každý form toto nevyřeší (moje chyba, neuvedl v předchozí ukázce kódu všechny formuláře, hlavně tento zákeřný formulář)
public function formAddProductSucceeded(Form $form, $values) {
$categories = $this->categoryManager->getAncestorsOfCategory($values->category);
$product = $this->productManager->addProduct($values, $categories);
$this->imageStorage->saveIcon($values->icon, $product->id);
foreach ($values->images as $image) {
$row = $this->imageManager->add($product->id);
$this->imageStorage->save($image, $row->image_id); //->save($image, $filename)
}
}
Nejdřív zjistím všechny nadřazené kategorie pomocí
catagoryManageru,
potom si uložím produkt do všech nadřazených kategorií (aby by byl produkt
„i5“ vidět v kategoriích intel, procesory, domácí počítače apod.)
pomocí productManageru.
Dále si pomocí imageStorage uložím ikonku produktu.
A nakonec si uložím všechny obrázky k produktu do databáze pomocí
imageManageru a do složky www/images/… pomocí už zmiňovaného
imageStorage. Tím jsem vyřešil i kolize názvů obrázků, protože názvy
souborů generuje databáze.
Kvůli tomuto formuláři potřebuju právě všechny čtyři managery v jedné
továrně.
Tak a teď teprve doufám, že to není velká prasárna, v tomto si nejsu vůbec jistý.
Editoval Milan Obrtlík (11. 9. 2015 11:51)
- jiri.pudil
- Nette Blogger | 1034
Tak pokud budeš mít na každý formulář samostatnou továrnu a jeden holt
vyžaduje více závislostí, tak si v té jedné továrně řekneš
o všechny, v tom nevidím problém :) Další možný krok je uklidit to pak
právě do fasády, tzn. uděláš si třídu třeba ProductFacade
,
do které celou tuhle logiku včetně závislostí schováš, a ve zpracování
formuláře už pak pracuješ jenom s tou fasádou