Komponenta a tovární metoda
- martinkobelka
- Člen | 4
Zkouším si podle dokumentace vytvořit komponentu za pomocí tovární metody. Problém je ale v tom, že v dokumentaci je uvedeno, že podle následujícího rozhraní by měla být při vytváření zavolána metoda create() Mám tedy následující tovární metodu a k ní komponentu.
namespace App\Components;
use Nette\Application\UI;
interface ICategoryFormFactory
{
/**
* @return CategoryForm
*/
public function create();
}
class CategoryForm extends Nette\Object
{
public function create()
{
$form = new UI\Form;
// mohu použít $this->database
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
}
Mě se ale při zavolání zavolá __construct() a metoda create zůstává mrtvá. Mohl by mi s tím prosím někdo poradit?
Takto se potom snažím vytvořit komponentu v prezenteru
/**
* Vytvoří komponentu formuláře
*/
protected function createComponentLoginForm(){
return $this->CategoryFormFactory->create();
}
Editoval martinkobelka (9. 6. 2017 10:33)
- David Matějka
- Moderator | 6445
Ahoj, tvoje „CategoryForm“ je ve skutecnosti uz sama o sobe tovarna na formular/komponentu. takze by se to melo jmenovat CategoryFormFactory a registrujes to jako sluzbu. (a vubec nebude existovat ICategoryFormFactory)
Ty tovarny na komponenty pres rozhrani slouzeji k tomu, kdyz si vytvoris komponentu (tridu, ktera dedi od UI\Control).
v tomhle pripade by to tedy vypadalo treba:
interface ICategoryFormFactory
{
/**
* @return CategoryForm
*/
public function create();
}
class CategoryForm extends UI\Control
{
protected function createComponentForm()
{
$form = new UI\Form;
// mohu použít $this->database
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
}
pak budes tedy v presenteru vytvaret pres to rozhrani tuhle komponentu a ta ma v sobe dalsi komponentu se samotnym formularem.
- martinkobelka
- Člen | 4
David Matějka napsal(a):
Ahoj, tvoje „CategoryForm“ je ve skutecnosti uz sama o sobe tovarna na formular/komponentu. takze by se to melo jmenovat CategoryFormFactory a registrujes to jako sluzbu. (a vubec nebude existovat ICategoryFormFactory)
Ty tovarny na komponenty pres rozhrani slouzeji k tomu, kdyz si vytvoris komponentu (tridu, ktera dedi od UI\Control).
v tomhle pripade by to tedy vypadalo treba:
interface ICategoryFormFactory { /** * @return CategoryForm */ public function create(); } class CategoryForm extends UI\Control { protected function createComponentForm() { $form = new UI\Form; // mohu použít $this->database $form->addSubmit('send', 'Odeslat'); $form->onSuccess[] = [$this, 'processForm']; return $form; } }
pak budes tedy v presenteru vytvaret pres to rozhrani tuhle komponentu a ta ma v sobe dalsi komponentu se samotnym formularem.
Však v presenteru vytvářím přes toto rozhraní.
/**
* @var ILoginFormComponentFactory
* @inject
*/
public $loginFormFactory;
/**
* Vytvoří komponentu formuláře
*/
protected function createComponentLoginForm(){
return $this->CategoryFormFactory->create();
}
Ale to řádek v createComponentLoginForm() mi zavolá konstruktor a ne metodu create. Funguje mi to jen takto.
/**
* Vytvoří komponentu formuláře
*/
protected function createComponentLoginForm(){
$form = $this->loginFormFactory->create();
return $form->createComponentLoginForm();
}
Editoval martinkobelka (9. 6. 2017 14:14)
- David Matějka
- Moderator | 6445
ale ta tva trida CategoryForm
neni komponenta, ale tovarna.
takze ty pomoci ICategoryFormFactory vytvoris instanci te CategoryForm.
jak jsem psal – pokud v te tride mit pouze definici formulare, tak to rozhrani nemusis pouzivat, jen registrujes CategoryForm jako sluzbu (respektive prejmenovane na CategoryFormFactory) a budes to vytvaret primo pomoci teto sluzby
pokud chces vytvorit komponentu, ktera v sobe ma dalsi formular, tak viz ten muj prispevek. jeste mrkni na https://doc.nette.org/…s/form-reuse
- martinkobelka
- Člen | 4
David Matějka napsal(a):
ale ta tva trida
CategoryForm
neni komponenta, ale tovarna. takze ty pomoci ICategoryFormFactory vytvoris instanci te CategoryForm.jak jsem psal – pokud v te tride mit pouze definici formulare, tak to rozhrani nemusis pouzivat, jen registrujes CategoryForm jako sluzbu (respektive prejmenovane na CategoryFormFactory) a budes to vytvaret primo pomoci teto sluzby
pokud chces vytvorit komponentu, ktera v sobe ma dalsi formular, tak viz ten muj prispevek. jeste mrkni na https://doc.nette.org/…s/form-reuse
Když vytvožím komponentu přesně podle tvého příspěvku, tak se mi zavolá při ale metoda __construct a ne create
Můj kod komponenty
<?php
namespace App\components;
use Nette\Application\UI\Control as Control;
use Nette\Application\UI\Form;
interface ILoginFormComponentFactory
{
/**
* @return LoginFormComponent
*/
public function create();
}
class LoginFormComponent extends Control {
public function createComponentLoginForm() {
$form = new Form;
// Získáme existující operace kalkulačky a dáme je do výběru operací.
$form->onSuccess[] = [$this, 'calculatorFormSucceeded'];
return $form;
}
}
Můj kod prenezenteru
/**
* @var ILoginFormComponentFactory
* @inject
*/
public $loginFormFactory;
/**
* Vytvoří komponentu formuláře
*/
protected function createComponentLoginForm(){
return $this->loginFormFactory->create();
}
Výsledek
Nette\MemberAccessException
Call to undefined method App\components\LoginFormComponent::render()
Ovšem v tutoriálu https://doc.nette.org/…s/form-reuse metoda render vůbec není.
Metoda create kterou implementuje nette vůbec nezavolá metodu create z mé komponenty. ale __construct(). To je to na co se celou dobu ptám proč. V tutoriálu je napsáno, že vygenerovaná metoda create zavolá metodu create z mého kontroleru
Editoval martinkobelka (9. 6. 2017 16:54)
- David Matějka
- Moderator | 6445
Když vytvožím komponentu přesně podle tvého příspěvku, tak se mi zavolá při ale metoda __construct a ne create
ano, to je spravne chovani. generovane tovarny vytvareji instance trid. nevolaji tvoji metodu
Ovšem v tutoriálu .. metoda render vůbec není.
j, to je bohuzel pravda. nejsnazsi render pro formular muze vypadat nasledovne:
public function render()
{
$this['form']->render();
}
V tutoriálu je napsáno, že vygenerovaná metoda create zavolá metodu create z mého kontroleru
kde to je napsany, ze to zavola tvoji metodu create?
- martinkobelka
- Člen | 4
David Matějka napsal(a):
Když vytvožím komponentu přesně podle tvého příspěvku, tak se mi zavolá při ale metoda __construct a ne create
ano, to je spravne chovani. generovane tovarny vytvareji instance trid. nevolaji tvoji metodu
Ovšem v tutoriálu .. metoda render vůbec není.
j, to je bohuzel pravda. nejsnazsi render pro formular muze vypadat nasledovne:
public function render() { $this['form']->render(); }
V tutoriálu je napsáno, že vygenerovaná metoda create zavolá metodu create z mého kontroleru
kde to je napsany, ze to zavola tvoji metodu create?
Díky tím jsi mi vše vyjasnil :)