Jak předat NetteTranslator do konstruktoru formuláře

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

Zdravím, potřeboval bych poradit jak předat translator do base třídy pro formuláře s využitím configu.

Mám zaregistrovanou službu v config.neon:

services
		translator:
			create: Test\NetteTranslator\Gettext::getTranslator
			...

A vytvořenou vlastní třídu form:

namespace Test;

abstract class Form extends Nette\Application\UI\Form {
	...
}
vvoody
Člen | 910
+
0
-
class FormFactory extends Nette\Object
{
	/**
	 * @var NetteTranslator\Gettext
	 */
	private $translator;

	public function injectTranslator(NetteTranslator\Gettext $translator)
	{
		$this->translator = $translator;
	}

	public function create()
	{
		$form = new Test\Form;
		$form->setTranslator($this->translator);
		return $form;
	}

}
services
	translator:
		create: Test\NetteTranslator\Gettext::getTranslator
		class: NetteTranslator\Gettext
	formFactory:
		class: FormFactory
class MyPresenter extends Nette\Application\UI\Presenter
{

	/**
	 * @var FormFactory
	 */
	private $formFactory;

	public function injectFormFactory(FormFactory $formFactory)
	{
		$this->formFactory = $formFactory;
	}

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

}

Je to úplne z hlavy tak čakaj hromadu preklepov a je to pre jednoduchosť úplne non-lazy.

Ale myslím že chceš programovať formulár v samostatnej triede. To môžeš riešiť napríklad dedením továrne:

class TestFormFactory extends FormFactory
{

	public function create()
	{
		$form = parent::create()
		$form->addText('name');
		...
		$form->onSuccess[] = callback($this, 'processForm');
		return $form;
	}

	public function processForm($form)
	{
		$values = $form->getValues();
		...
	}

}

Potom si presenter nechá injectnúť TestFormFactory namiesto FormFactory.

edit: samozrejme ešte treba upraviť názov a triedu služby v configu,

services
	translator:
		create: Test\NetteTranslator\Gettext::getTranslator
		class: NetteTranslator\Gettext
	testFormFactory:
		class: TestFormFactory

Editoval vvoody (23. 2. 2013 16:29)

czm4rty
Člen | 29
+
0
-

Ahoj, díky za tvé řešení. Ještě otázka. Do teď jsem vytvářel formuláře přes Interface a měl je všechny obsažené v configu v sekci factories.

components:
	factories:
		- Test\ITestFormFactory

interface ITestFormFactory {

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

class TestForm extends Form {
}

Když vložím TestFactoryForm do sekce factory v configu, tak to zahlasí:

No service of type Test\TestFormFactory found. Make sure the type hint in Test\TestPresenter::injects() is written correctly and service of this type is registered.

Rád bych se vyhnul interfacům. Nevíš jak?

vvoody
Člen | 910
+
0
-
factories:
	testFormFactory:
		implement: Test\ITestFormFactory

czm4rty napsal(a):
Rád bych se vyhnul interfacům. Nevíš jak?

Použi moje riešenie, tam interface niesu.

czm4rty
Člen | 29
+
0
-

Zkousim to, ale hleda to interface:

Interface Test\TestFormFactory has not been found.

TestFormFactory ted vypada, tak jak jsi navrhoval:

class TestFormFactory extends FormFactory {
    public function create() {
        $form = parent::create();
	return $form;
    }
}
vvoody
Člen | 910
+
0
-

Tuto:

vvoody napsal(a):

factories:
	testFormFactory:
		implement: Test\ITestFormFactory

som ti len ukazoval ako fixnúť tvoju chybu pri použití generovaných factories z interfaců.

Ak ich nechceš použiť, tak na tento config zabudni a použi ten ktorý som uviedol v prvom poste, čiže každú továreň ktorú vytvoríš, zaregistruj ako službu (services).

czm4rty
Člen | 29
+
0
-

Ok, díky