Nefunkční generování továrničky
- lukasklekner
- Člen | 24
Ahoj mám problém s generování továrničky a fakt is nevím rady,
dělám to podle tohoto návodu – https://doc.nette.org/…s/form-reuse
A můj kód, který jsem si upravil vypadá takto (trochu se liší od toho
v tutorialu, ale myslím že to by problém být neměl)
CategoryForm:
class CategoryForm extends UI\Control {
private $database;
public $onCategorySave;
public function __construct(Connection $database) {
parent::__construct();
$this->database = $database;
}
public function createComponentForm() {
$form = new UI\Form;
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm($form) {
$this->onCategorySave($this, $category);
}
}
interface ICategoryFormFactory
{
/** @return \CategoryForm */
function create();
}
Presenter:
class HomepagePresenter extends BasePresenter {
public $categoryFormFactory;
public function __construct(ICategoryFormFactory $categoryFormFactory) {
$this->categoryFormFactory = $categoryFormFactory;
}
protected function createComponentCategoryForm() {
$control = $this->categoryFormFactory->create();
$control->onCategorySave[] = function(CategoryControl $control, $category) {
$this->redirect('this');
};
return $control;
}
}
Config:
- App\Forms\ICategoryFormFactory
Moc Vám děkuji za rady. :)
- h4kuna
- Backer | 740
Nějaká exception by byla?
Jinak na první pohled CategoryForm a
ICategoryFormFactory jsi uvedl v jednom bloku tak to máš asi
v jednom souboru? Ale neuvedl jsi namespace tak jen hádám.
U rozhraní podle, kterýho se má generovat továrna máš v anotaci return namespace od rootu \CategoryForm
interface ICategoryFormFactory
{
/** @return \CategoryForm */
function create();
}
V configu
- App\Forms\ICategoryFormFactory
Odhaduji že by tam mělo být
- ICategoryFormFactory
Editoval h4kuna (6. 7. 2017 19:45)
- lukasklekner
- Člen | 24
h4kuna napsal(a):
Nějaká exception by byla?
Jinak na první pohled CategoryForm a ICategoryFormFactory jsi uvedl v jednom bloku tak to máš asi v jednom souboru? Ale neuvedl jsi namespace tak jen hádám.U rozhraní podle, kterýho se má generovat továrna máš v anotaci return namespace od rootu \CategoryForm
interface ICategoryFormFactory { /** @return \CategoryForm */ function create(); }
V configu
- App\Forms\ICategoryFormFactory
Odhaduji že by tam mělo být
- ICategoryFormFactory
Díky za odpověď. Jo dobře omlouvám se zkusím všechno zodpovědět.
Takže mám to v jednom souboru.
Namespace: namespace App\Forms;
V configu jsem to předělal a aplikace mi vyhodila tuto chybu: Class ICategoryFormFactory used in service ‚28_ICategoryFormFactory‘ not found
- lukasklekner
- Člen | 24
CZechBoY napsal(a):
Tak to potom uveď
@return CategoryForm
, protože jsou nejspíš ve stejném namespace.
Uvedl jsem @return CategoryForm:
interface ICategoryFormFactory
{
/** @return CategoryForm */
function create();
}
- lukasklekner
- Člen | 24
CZechBoY napsal(a):
a uz funguje? :-))
Promin jsem dement :D Nefunguje právě…
- lukasklekner
- Člen | 24
CZechBoY napsal(a):
jo počkej, tobě to píše jinou hlášku :D
musíš při registraci služby zadat fqdn – celé jméno třídy i s namespace – tzn.App\Forms\ICategoryFormFactory
Ty jo ted mi to hlásí tudle chybu… Call to undefined method App\Forms\CategoryForm::render()
- lukasklekner
- Člen | 24
CZechBoY napsal(a):
No jasne… jak se ma ta komponenta vyrenderovat? Jestli ti staci jen form tak by melo stacit
echo $this['form']->render();
To mám přidat do metody redner ? V tý třídě CategoryForm ?
- lukasklekner
- Člen | 24
Hele tk už mi to hlásí chybu, že proměnná category neni deklarovaná
public function processForm($form) {
$this->onCategorySave($this, $category);
}
Což mi je jasný, ale moc nevím co s tím… Snažím se o vytvoření callbacku a dělám to jk jsem psal výše podle návodu, ale nejde to prostě… Snad pomůžete dík moc
- lukasklekner
- Člen | 24
Oli napsal(a):
No záleží, kde se má ta proměnná
$category
vzít? Z formuláře nebo z GET parametru? Je to idčko, ActiveRow nebo entita? Pokud je to z formuláře tak$form->category
, pokud z presenteru, tak přes konstruktor (jesltiže bez toho nedává komponenta smysl) nebo přes setr metodu…
Okej ted jsem fkt uplně mimo :D Nemohl by si mi napsat nějaký příklad jendoduchý na toto téma ? Zkrátka vůbec nechápu jak ten callback použít… Díky moc
- Oli
- Člen | 1215
Jsem na mobilu, tak snad postačí tohle https://doc.nette.org/…/smartobject#…. Případně to víc rozvedu, jestli to z toho nebude patrné :)
- petrkasnal
- Člen | 42
Díky moc všem už jsem to dokázal jsem blb… Ale mám ještě jeden dotaz
šlo by to udělat bez interface – ICategoryFormFactory. Zkousil jsem to
takhle:
CategoryForm:
class CategoryForm extends UI\Control {
private $database;
public $onCategorySave;
public function __construct(Connection $database) {
$this->database = $database;
}
public function render() {
echo $this['form']->render();
}
public function createComponentForm() {
$form = new UI\Form;
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm($form) {
$this->onCategorySave();
}
}
Presenter:
class HomepagePresenter extends BasePresenter {
public $categoryForm;
public $userManager;
public function __construct(CategoryForm $categoryForm) {
$this->categoryForm = $categoryForm;
}
public function createComponentCategoryForm() {
$control = $this->categoryForm->createComponentForm();
$control->onCategorySave[] = function() {
$this->redirect('this');
};
return $control;
}
}
Ale program mi vyhodil tuto chybu: Cannot read an undeclared property Nette\Application\UI\Form::$onCategorySave.
- David Matějka
- Moderator | 6445
muzes si udelat pouze tovarnu na form, pak to ale uz nebude „formular jako komponenta“. kdyz chces form jako komponentu, tak ten interface (resp tovarnu) mit musis
- Šaman
- Člen | 2666
Ty lítáš v základech OOP a ještě se ti do toho motají věci
specifické pro Nette.
V tomhle případě to ale s Nette nesouvisí – v presenteru si pomocí
tovární metody vytvoříš nikoliv instanci CategoryForm
, ale jen
UI\Form
(podívej se na kód
createComponentForm()
).
A ten UI\Form
o nějaké $onCategorySave
vůbec
neví. Proto ta chyba.
Bez interface to jde, ale pak si musíš sám napsat tovární třídu pro
vytvoření CategoryForm
. Nebo nepoužívat továrnu a v metodě
$homepagePresenter->createComponentCategoryForm()
použít
operátor new
. (Nedoporučuje se, ale fungovat to bude.)
Ideální je se ale nejdřív seznámit s Nette tím, že budeš psát kód podle ukázek a teprve až je pochopíš, tak si zkoušet vlastní řešení.