Nefunkční metoda setDefaults

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
dreazer
Člen | 7
+
0
-

Ahoj všichni. Mám takový začátečnický problém.

Mám komponentu:

public function createComponentPostForm() {
    $control = $this->iPostFormFactory->create();
    $control->onCategorySave[] = function($values, $postId) {
        $post = $this->postManager->getRecordById($postId);
        $post->update($this->postManager->getValuesForPost($values));
        $this->presenter->redirect('this');
    };
    return $control;
}

Továrna na vytvoření komponenty vypadá takto:

class PostFormFactory extends UI\Control {

    public function render() {
        echo $this['formPost']->render();
    }

    public function createComponentFormPost() {
        $form = new UI\Form;
        $form->addText('name', 'Jméno příspěvku:');
        $form->addText('date', 'Datum přidání:);
        $form->addSubmit('send', 'Odeslat');
        $form->onSuccess[] = [$this, 'createPostSucceeded'];
        return $form;
    }

    public function createPostSucceeded($form, $values) {
        $postId = $this->presenter->getParameter('postId');
        $this->onCategorySave($values, $postId);
    }
}

interface IPostFormFactory {

    /** @return PostFormFactory */
    function create();
}

Todle všechno funguje v pořádku zkrátil jsem to. A dále mám metodu na upravení formuláře ve stejném presenteru jako metodu na vytvoření komponenty

public function actionEdit($postId) {
		$post = $this->postManager->getRecordById($postId);
        if (!$post) {
            $this->error('Příspěvek nebyl nalezen');
        }
        $this['postForm']->setDefaults(array(
            'name' => $post->name,
            'date' => $post->date->format('d.m.Y')
        ));
}

A zde nastává problém: Call to undefined method App\Forms\ProjectFormFactory::setDefaults().
Nevím čím přesně to je, ale myslím si, že vracím z komponenty postForm nevracím formulář. Ale nejspíš se pletu budu moc vděčný za každou radu díky moc :)

Šaman
Člen | 2666
+
0
-

Ano. $this['postForm'] je instance PostFormFactory.
Musíš volat $this['postForm']['formPost']. (Protože vlastní formulář vytváří v té komponentě až metoda createComponentFormPost()).

Můžeš si ale vytvořit vlastní továrnu a v ní vracet rovnou formulář. Ukázku mám na Gistu.
(Tebe zajímá jen samotná FooFormFactory.php a její použití v presenteru. Řešení save, beforeSave apod. neřeš a take nepotřebuješ FormFactory, která připraví a nastaví některé věci všem formulářům. Místo ní v továrně rovnou vytvoříš new UI\Form.)

dreazer
Člen | 7
+
0
-

Ty jo díky moc za odpověď. To tvoje řešení je opravdu zajímavé :) Hele a to tvoje řešení je v pořádku z hlediska správnosti kódu ? Dělam to do práce totiž. Ale jinak fakt hezký děkuji

dreazer
Člen | 7
+
0
-

A samozřejmě funguje i řešení $this[‚postForm‘][‚formPost‘]

Šaman
Člen | 2666
+
+1
-

Jasně že je to čisté řešení.
Ty vůbec nepotřebuješ komponentu, ty potřebuješ formulář. Ta tvoje komponenta ho jen obaluje, ale nic užitečného nepřidává (třeba vlastní šablonu, nebo flashmessage). V render metodě komponenty jen vykresluješ ten formulář, nic víc. Ale taky ho ta komponenta skrývá, což není dobré když ho chceš z presenteru upravovat.
Navíc prostou tovární třídu si můžeš předávat jako službu. Konkrétní instanci formuláře si pak vytvořiš tam, kde potřebuješ.
Když to máš jako komponentu, tak musíš zajistit, abys pokaždé dostal novou instanci té komponenty – proto ta magie s IPostFormFactory a s generovanými továrničkámi. (Ta problematika je popsaná třeba tady.)
V tom řešení s FormFactory namísto komponenty je řešit nemusíš. (Ty defacto píšeš onu továrnu, kterou článek popisuje jako čisté řešení. Akorát je složitější, protože ten formulář kompletně připraví a nastaví mu nějakou obsluhu.)

Editoval Šaman (10. 7. 2017 10:29)