Service ‚application.1‘ (type of App\Presenters\AccountPresenter): Service of type App\Forms\SignInFormFactory

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Ahoj,

v app mám složku Forms, kde mám FormFactory.php a SignInFormFactory.php. V AccountPresenter.php se snažím vykreslit formulář, ale nejde to kvůli chybové hlášce: Service 'application.1' (type of App\Presenters\AccountPresenter): Service of type App\Forms\SignInFormFactory

Takto vypadá common.neon: https://pastebin.com/SD5bgGq5

David Matějka
Moderator | 6445
+
+1
-

Stejný problém jako tady https://forum.nette.org/…t-or-default, extendujes presenter..

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Děkuji, funguje.

Nicméně potřebuji ve formuláři získat parametr z GETu a po odeslání formuláře potřebuji přesměrovat uživatele. Jak toho docílím?

dakur
Člen | 493
+
+4
-

@bdinvpvsmvpscuiqpc Myslím, že jsi to špatně pochopil. Třídy se nedědí proto, že potřebuješ využívat jejich metody, ale proto, že jsou významově potomkem – tj. mají s rodičem něco společného. Např. třídy Animal a Dog mají evidentně něco společného, stejně jako např. Feedback a FeedbackForCampaign či FeedbackForMaterial. Pokud proto ovšem nemáš opravdu důvod, je nejlepší vůbec nedědit – typicky se to dá řešit buď interfacem (např. ten feedback), či kompozicí.

Ve tvém případě v SignInFormFactory se dají využít eventy anebo jestli ti to přijde moc složité, můžeš si prostě udělat callback:

// form factory
class SignInFormFactory
{
  // ...
  public function create(callable $callback): void
  {
    // ...
    $form->onSuccess[] = function (stdClass $values, $backlink) {
      $callback($values->name, $values->password);
    };
  }
}

// presenter
class AccountPresenter
{
  // ...
  protected function createComponentSignInForm(): Form
  {
    return $this->signInFactory->create(function (string $username, string $password) {
      $this->user->login($username, $password);
      $this->redirect(...);
    });
  }
}

Tímto způsobem vlastně můžeš říct, co se má provést uvnitř form factory, ale definuješ to v presenteru, tudíž máš přístup ke všem službám/funkcionalitám, které tam jsou.

Editoval dakur (3. 3. 2021 7:42)

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Děkuji za odpověď. Vyřešil jsem to callbackama.

Při vytváření formuláře potřebuji získat GET parametr, abych nastavil atribut inputu. Jak to lze udělat?

Kamil Valenta
Člen | 822
+
0
-

A jak jsi to zkoušel udělat?

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Pokud není nastaven GET parametr, tak potřebuji nastavit inputu autofocus.

Zkoušel jsem to udělat takto:

$value = $this->getParameter('name');

if ($value == null) {
	$name->setHtmlAttribute('autofocus');
}

Nicméně to v SignInFormFactory nejde udělat. V Presenteru to jde.

Kamil Valenta
Člen | 822
+
0
-
$value = $this->getPresenter()->getParameter('name');

?

Nebo ten „name“ předat komponentě jako závislost, jak ji presenter vytvoří. Komponenta by moc neměla sahat do „vnějšího světa“.

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Vyzkoušel jsem nyní callback a zjistil jsem, že nefunguje. Po odeslání formuláře se nic nestane.

Takto vypadá můj SignInFormFactory.php a takto komponenta v AccountPresenter.php.

Marek Bartoš
Nette Blogger | 1280
+
+1
-

$variable; nic neudělá. $variable(); zavolá funkci, co je v proměnné uložená

bdinvpvsmvpscuiqpc
Člen | 57
+
0
-

Super, děkuji. Nyní to již funguje.