Forms – $this->translator je NULL

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

Zdravím,

robím si formuláre podľa dokumentácie: https://doc.nette.org/cs/forms#… avšak aj pri použití $form->setTranslator($this->translator); sa jednotlivé texty nepreložia. Pri otestovaní hodnoty pomocou Tracy debuggeru, je vlasťnosť translator ako NULL.

Moja trieda na formulár vyzerá následovne:

namespace App\Forms;

use Nette\Application\UI\Form;

class SignInFormFactory extends BaseFormFactory
{
    public function create()
    {
        $form = new Form;
        Debugger::dump($this->translator);
        $form->setTranslator($this->translator);

        $form->addGroup();
        $form->addText('username')
            ->setAttribute('autofocus')
            ->setAttribute('placeholder', 'forms.login.username')
            ->setRequired('forms.login.username_empty')
            ->addRule(Form::MIN_LENGTH, 'forms.register.username_min_length', 3)
            ->getLabelPrototype()->setName(NULL);

        $form->addPassword('password')
            ->setAttribute('placeholder', 'forms.login.password')
            ->setRequired('forms.login.password_empty')
            ->getLabelPrototype()->setName(NULL);

        $form->addSubmit('submit', 'forms.login.sign_in')
            ->setAttribute("class", "btn-lg btn-success btn-block");

        return $form;
    }
}

kde BaseFormFactory mám na injectovanie toho translatora:

namespace App\Forms;

class BaseFormFactory extends Nette\Object
{
    /** @var \Kdyby\Translation\Translator @inject */
    public $translator;
}

Avšak ten translator sa nevloží do toho objektu ako to je napríklad v Presenteri. Skúšal som to aj pridať ako service, bez zmeny. Nenapadá mi prečo to tak je a zrejme to riešiť metódou

$form = (new SignInFormFactory($this->translator))->create();

nie je najideálnejšie. Vopred díky za pomoc.

Editoval Lkopo (27. 2. 2017 18:17)

Matey
Člen | 142
+
+2
-

Problém je v tom že @inject funguje automaticky len v presnteroch.

Prečítaj si https://forum.nette.org/…ory-nebo-jne je tam riešenie cez decorator.

Lkopo
Člen | 65
+
+1
-

Aha,

keď som to správne pochopil, do BaseFormFactory mám pridať metódu setTranslator:

    /** @var \Kdyby\Translation\Translator */
    public $translator;

    public function setTranslator(\Kdyby\Translation\Translator $translator)
    {
        $this->translator = $translator;
    }

A potom v config.neon vložiť nasledujúci riadok:

decorator:
    App\Forms\BaseFormFactory:
        setup:
            - setTranslator

Avšak nič sa nezmenilo.

David Matějka
Moderator | 6445
+
0
-

ukaz, jak tu SignInFormFactory pouzivas v presenteru

Lkopo
Člen | 65
+
0
-

Následovne, vytvorím inštanciu a zavolám na ňu metódu create:

    protected function createComponentSignInForm()
    {
        $form = (new SignInFormFactory())->create();

        // call method signInFormSucceeded() on success
        $form->onSuccess[] = [$this, 'signInFormSucceeded'];
        return $form;
    }

Postupoval som podľa toho prvého návodu spomenutý v úvodnom príspevku.

CZechBoY
Člen | 3608
+
+1
-

Ne, musíš tu factory registrovat jako službu v konfiguráku (.neon) a potom v presenteru vyžádat (inject/konstruktor) tu službu.

services:
	- App\MujFormFactory
class MujPresenter extends Presenter
{
	/**
	 * @var \App\MujFormFactory
	 * @inject
	 */
	public $mujFormFactory;

	protected function createComponentMujForm()
	{
		$form = $this->mujFormFactory->create();
		...
		return $form;
	}
}

Editoval CZechBoY (27. 2. 2017 19:08)

Lkopo
Člen | 65
+
0
-

Aháá, public. Ja som to mal ako private. Vďaka pekne, už to ide :)

CZechBoY
Člen | 3608
+
+1
-

Pokud bys chtěl private (ano dobrá volba) tak musíš použít inject metody, případně konstruktor..

class MujPresenter extends Presenter
{
    /**
     * @var \App\MujFormFactory
     */
    private $mujFormFactory;

	/* na jméně metody až tak nezáleží, musí začínat na "inject" */
	public function injectMujFormFactory(\App\MujFormFactory $mujFormFactory)
	{
		$this->mujFormFactory = $mujFormFactory;
	}

    protected function createComponentMujForm()
    {
        $form = $this->mujFormFactory->create();
        ...
        return $form;
    }
}

Editoval CZechBoY (27. 2. 2017 19:44)

Lkopo
Člen | 65
+
0
-

Tak som zvyknutý na tú enkapsuláciu, ale v prípade potreby to ponechám ako public. Ale ďakujem za riešenie, je až zaujímavé koľko toho Nette ponúka :).