Form is not anchored and therefore can not determine whether it was submitted při přechodu na 2.4
- BuMoRi
- Člen | 109
Ahoj, při přechodu z 2.3 na 2.4 dostávám 500 a v logu mám: Form is
not anchored and therefore can not determine whether it was submitted.<| in
\libs\Nette\Forms\Form.php:400
Znamená to, že musím místo Nette\Forms\Form používat
Nette\Application\UI\Form? Nebo by mohla být chyba jinde?
- BuMoRi
- Člen | 109
Prosimtě callstack myslíš z Tracy? Mně totiž vyskočí 500, aniž by to
spadlo do Tracy a jen v logu mám tu chybu.
Zkusím napsat kde chyba vzniká, jestli by tě něco napadlo:
Vytvoření formuláře je pomocí vlastní knihovny postavené na Nette
<?php
protected function createComponentSearchForm($name)
{
$form = $this->addForm('searchForm');
...
?>
Metoda addForm:
<?php
public function addForm($name, $ajax=false, $display=true, $csrf=false)
{
$form = new \Ownlib\Forms\AppForm($this, $name);
...
?>
Třída AppForm:
<?php
class AppForm extends \Ownlib\AppComponent
{
/** @var \Nette\Application\UI\Form */
private $form;
...
public function __construct($parent = NULL, $name = NULL)
{
parent::__construct();
$this->formname = $name;
$this->form = new \Nette\Application\UI\Form($this, $this->formname);
if ($this->form->isSubmitted()) {
$this->handleShow(null);
$this->invalidateControl();
}
...
?>
Tady jsem udělal oproti předchozím verzím změnu v tom, že parent construct je bez parametrů. Třída je poděděná ze třídy Component (2.4) a tam byly v constructoru v předchozích verzích Nette (2.1–2.3) 2 parametry – viz Component (2.3)
Padá mi to na té podmínce $this->form->isSubmitted(), kde mi metoda isAnchored() vrátí NULL, zatímco ve starších verzích mi vracela presenter.
Jsou tyto informace k něčemu? Budu vděčný za jakoukoliv pomoc.
- David Matějka
- Moderator | 6445
máš to celé divné, ale hlavní problém je, že smazáním těch parametrů pro parent::__construct si zrušil připojení do stromu komponent. jako hotfix pod to můžeš přidat pod to parent::__construct:
$parent->addComponent($this, $name);
ale bude lepší, když necháš připojování do stromu komponent na nette, tzn všude využiješ továrny na komponenty, takže v tom tvém Appform budeš mít
public function createComponentForm()
{
$form = new UI\Form();
...
return $form;
}
to, co máš v té isSubmitted podmínce, můžeš dát do callbacku na onAnchor událost
- BuMoRi
- Člen | 109
Ahoj, zkusil jsem rady, které mi napsali CZechBoY a David, ale stále se to nedaří rozchodit:
1. Místo parametrů v constructoru přidat addComponent
výsledek:
<?php
PHP Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given in …\AppForm.php:302
Fatal Error: ReflectionClass::getMethod(): Internal error: Failed to retrieve the reflection object in ...\libs\Ownlib\Forms\AppForm.php:304
?>
V AppForm zmíněné řádky:
<?php
final public function __call($procedureName, $arguments=array())
{
try {
$ref = new \ReflectionObject($this->form); //řádek 302
$ret = null;
if (!$ref->getMethod($procedureName)) throw new \Exception('Procedure `'.$procedureName.'` doesn`t exist!'); //řádek 304
?>
2. Továrna: vyhazuje stejné chyby, jako když formulář vytvářím v constructoru
3. Dal jsem místo isSubmitted podmínky: $this->onAnchor[] = function()
{…
Dostávám
<?php
[Nette\UnexpectedValueException]: |>Method homePresenter::createComponentSearchForm() did not return or create the desired component.<| in \libs\Nette\ComponentModel\Container.php:176
?>
Nevím jestli jsem to s onAnchor správně pochopil. Také jsem zapomněl
napsat, že metoda addForm je v Presenteru, který je rodič všech
BasePresenterů v jednotlivých modulech.
Prosím o radu, jestli jstem onAnchor správně použil, případně co ještě
zkusit…
- David Matějka
- Moderator | 6445
- to je tvuj kod, takze dle callstacku zjisti, odkud se to vola a jakto, ze je this->form prazdne
- …
- tak z te metody vrat komponentu, viz https://doc.nette.org/…n/presenters#…