Automatické vytvoření komponenty v presenteru

Petr Parolek
Člen | 455
+
0
-

Ahoj, dají se prosím nějak automaticky vytvářet nové metody? Jde mi o registraci komponent např. z pole do presenteru.

Ukázka konceptu:

<?php

declare(strict_types=1);

namespace App\Presenters;


final class HomepagePresenter extends BasePresenter
{
	public function renderDefault(): void
	{
		$this->template->anyVariable = 'any value';
	}

	foreach ($components as $componnt) {
		public function createComponent . $component->name . Form()
		{
	  		return $this->$component->factoryName->create($this->getParameter('id'));
		}
	}
}

Jde tohle nějak v PHP, potažmo v Nette? Klidně i přes DI extension

Editoval ppar (10. 2. 2020 11:21)

Marek Bartoš
Nette Blogger | 1167
+
+4
-
protected function createComponent(string $name): ?IComponent
{
  if ($this->componentManager->has($name)) {
    return $this->componentManager->create($name);
  }

  return parent::createComponent($name);
}
Petr Parolek
Člen | 455
+
0
-

ale takhle to nejde, když mám víc komponent v presenteru.

Marek Bartoš
Nette Blogger | 1167
+
+3
-

createComponent volá tvé createComponentExample metody. Takže v ní můžeš pracovat s tím svým polem a vrátit komponentu z ní a createComponentExample metody vůbec nemít.

Petr Parolek
Člen | 455
+
0
-

nechápu, jak to myslíš, mohl bys mi prosím ukázat přímo na mém ukázkovém kodě?

Mabar napsal(a):

protected function createComponent(string $name): ?IComponent
{
  if ($this->componentManager->has($name)) {
    return $this->componentManager->create($name);
  }

  return parent::createComponent($name);
}

Protože nemám nápad, kam nacpat cyklus

Editoval ppar (10. 2. 2020 11:43)

Marek Bartoš
Nette Blogger | 1167
+
0
-

Nepotřebuješ žádný cyklus, tahle metoda vrací konkrétní komponentu, když ji použiješ. (Např. $this['example'] nebo {control example})

protected function createComponent(string $name): ?IComponent
{
  if (isset($this->components[$name])) {
    return $this->components[$name];
  }

  return parent::createComponent($name);
}

Cyklus si můžeš dát max do šablony

{foreach $components as $name => $component} {
  {control $component}
}
Petr Parolek
Člen | 455
+
0
-

Teď na mě řve ze šablony:

Nette\InvalidArgumentException
Component with name 'someForm' does not exist.

Editoval ppar (10. 2. 2020 12:36)

Šaman
Člen | 2635
+
0
-

ppar: Ukaž ten kód v presenteru.

Kcko
Člen | 465
+
0
-

My to řešíme vlastní komponentou která je poděděná od

<?php

abstract class Control extends Nette\Application\UI\Control

	// implements autoloading components by name
	// lookups in namespace global and module namespace
	protected function createComponent($name)
	{
		$component = parent::createComponent($name);

		// pokud se nepodari najit tovarnicku na komponentu, zkusime autoload dle jmena
		if (!$component instanceof IComponent) {

			$componentFactory = $this->presenter->getControlFactory();

			$component = $componentFactory->create($this, $name);

		}

		return $component;
	}

?>

Třída má víc metod, ale tohle by to mělo dělat, pak nemusíme v presenteru vytvářet komponentu přes CreateComponentXXX ale rovnou si ji si ji vypíši v Latte a systém si ji najde a zinstancuje.

A pokud má mít nějaké výchozí parametry, tak máme v DB nastavenou komponentu s Presenteru ke stránce s výchozím configem, který je stále možné v LATTE nebo Presenteru přepsat (pokud je to potřeba).

Editoval Kcko (10. 2. 2020 14:48)

Petr Parolek
Člen | 455
+
0
-

jak s touto třídou pracuješ? Klasicky vytvořím komponentu, akorát nebudu dědí od Nette\Application\UI\Control, ale od Bar\Foo\Control?

Editoval ppar (10. 2. 2020 15:14)

Kcko
Člen | 465
+
0
-

Máme ještě FrontControl s nějakým dalším chováním, ale to je jen kvůli našemu systému, která od této abstraktní dědí.
Mělo by Ti stačit dědit rovnou od této abstraktní.

Petr Parolek
Člen | 455
+
0
-

@kiCkZ jak mám komponentu načíst v presenteru?

EDIT: Udělal jsem ukázku na https://github.com/…nets-sandbox – háže mi to stále, že komponenta neexistuje – Nette\InvalidArgumentException Component with name 'signInForm' does not exist, did you mean 'signUpForm'?

Editoval ppar (10. 2. 2020 18:49)

Kcko
Člen | 465
+
0
-

ppar napsal(a):

@kiCkZ jak mám komponentu načíst v presenteru?

EDIT: Udělal jsem ukázku na https://github.com/…nets-sandbox – háže mi to stále, že komponenta neexistuje – Nette\InvalidArgumentException Component with name 'signInForm' does not exist, did you mean 'signUpForm'?

Koukám do kódu, je to trošku složitější, je to víc kontrolek a továrna dohromady, udělám Ti přes víkend demo (dřív to nestihnu).

Petr Parolek
Člen | 455
+
0
-

v čem složitější?

Kcko
Člen | 465
+
0
-

@ppar dej mi e-mail, zítra ti to pošlu, už mi to funguje (na 2.3 a a 2.4), pošlu ti všechny potřebné soubory a trošku je očistím od našich věcí.

Budou to nějaké 3 – 4 soubory.

Petr Parolek
Člen | 455
+
0
-

díky, mail máš na msilu