Składanie presenterów z traitów
*******************************
.[perex]
Jeśli potrzebujesz zaimplementować tę samą funkcjonalność w wielu presenterach (np. weryfikację zalogowania użytkownika), typowym podejściem jest umieszczenie kodu we wspólnym przodku. Inną możliwością jest utworzenie jednozadaniowych [traitów |nette:introduction-to-object-oriented-programming#Traity].
Zaletą traitów jest to, że każdy presenter może włączyć tylko te traity, których faktycznie potrzebuje, zwłaszcza że PHP nie obsługuje dziedziczenia wielokrotnego.
Traity te mogą wykorzystać fakt, że przy tworzeniu instancji presentera wywoływane są kolejno wszystkie [metody inject |inject-method-attribute#Metody inject*()]. Musisz tylko zadbać o to, aby nazwa każdej metody inject była unikalna we wszystkich użytych traitach i w samym presenterze.
Traity mogą podpiąć kod inicjalizacyjny do zdarzeń [onStartup albo onRender |application:presenters#Zdarzenia].
Przykłady:
```php
trait RequireLoggedUser
{
public function injectRequireLoggedUser(): void
{
$this->onStartup[] = function () {
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in', $this->storeRequest());
}
};
}
}
trait StandardTemplateFilters
{
public function injectStandardTemplateFilters(TemplateBuilder $builder): void
{
$this->onRender[] = function () use ($builder) {
$builder->setupTemplate($this->template);
};
}
}
```
Presenter po prostu używa potem tych traitów:
```php
class ArticlePresenter extends Nette\Application\UI\Presenter
{
use StandardTemplateFilters;
use RequireLoggedUser;
}
```
Składanie presenterów z traitów
Jeśli potrzebujesz zaimplementować tę samą funkcjonalność w wielu presenterach (np. weryfikację
zalogowania użytkownika), typowym podejściem jest umieszczenie kodu we wspólnym przodku. Inną możliwością jest utworzenie
jednozadaniowych traitów.
Zaletą traitów jest to, że każdy presenter może włączyć tylko te traity, których faktycznie potrzebuje, zwłaszcza że
PHP nie obsługuje dziedziczenia wielokrotnego.
Traity te mogą wykorzystać fakt, że przy tworzeniu instancji presentera wywoływane są kolejno wszystkie metody inject. Musisz tylko zadbać
o to, aby nazwa każdej metody inject była unikalna we wszystkich użytych traitach i w samym presenterze.
Traity mogą podpiąć kod inicjalizacyjny do zdarzeń onStartup albo onRender.
Przykłady:
trait RequireLoggedUser
{
public function injectRequireLoggedUser(): void
{
$this->onStartup[] = function () {
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in', $this->storeRequest());
}
};
}
}
trait StandardTemplateFilters
{
public function injectStandardTemplateFilters(TemplateBuilder $builder): void
{
$this->onRender[] = function () use ($builder) {
$builder->setupTemplate($this->template);
};
}
}
Presenter po prostu używa potem tych traitów:
class ArticlePresenter extends Nette\Application\UI\Presenter
{
use StandardTemplateFilters;
use RequireLoggedUser;
}