Nette Documentation Preview

syntax
Modell
******

Wenn unsere Anwendung wächst, werden wir bald feststellen, dass wir ähnliche Datenbankoperationen an verschiedenen Stellen und in verschiedenen Präsentatoren durchführen müssen, um beispielsweise die neuesten veröffentlichten Artikel zu erfassen. Wenn wir unsere Anwendung verbessern, indem wir den Artikeln eine Markierung hinzufügen, die den Status "in Arbeit" anzeigt, müssen wir auch alle Standorte in unserer Anwendung durchgehen und eine Where-Klausel hinzufügen, um sicherzustellen, dass nur fertige Artikel ausgewählt werden.

An diesem Punkt wird die direkte Arbeit mit der Datenbank unzureichend, und es wird klüger sein, uns mit einer neuen Funktion zu helfen, die veröffentlichte Artikel zurückgibt. Und wenn wir später eine weitere Klausel hinzufügen (z. B. um keine Artikel mit einem zukünftigen Datum anzuzeigen), müssen wir unseren Code nur an einer Stelle bearbeiten.

Wir platzieren die Funktion in der Klasse `PostFacade` und nennen sie `getPublicArticles()`.

Wir erstellen unsere Modellklasse `PostFacade` im Verzeichnis `app/Model/`, die sich um unsere Artikel kümmert:

```php .{file:app/Model/PostFacade.php}
<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}
```

In der Klasse übergeben wir die Datenbank Explorer:[api:Nette\Database\Explorer]. Damit nutzen wir die Leistungsfähigkeit des [DI-Containers |dependency-injection:passing-dependencies].

Wir werden zu `HomePresenter` wechseln, das wir so bearbeiten, dass wir die Abhängigkeit von `Nette\Database\Explorer` loswerden und durch eine neue Abhängigkeit von unserer neuen Klasse ersetzen.

```php .{file:app/UI/Home/HomePresenter.php}
<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}
```

Im Abschnitt use verwenden wir `App\Model\PostFacade`, so dass wir den PHP-Code auf `PostFacade` verkürzen können. Wir fordern dieses Objekt im Konstruktor an, schreiben es in die Eigenschaft `$facade` und verwenden es in der Methode renderDefault.

Der letzte verbleibende Schritt besteht darin, dem DI-Container beizubringen, dieses Objekt zu erzeugen. Dies geschieht in der Regel durch Hinzufügen eines Aufzählungspunkts in der Datei `config/services.neon` im Abschnitt `services`, in dem der vollständige Klassenname und die Konstruktorparameter angegeben werden.
Dadurch wird es sozusagen registriert, und das Objekt wird dann **service** genannt. Dank eines Zaubers namens [Autowiring |dependency-injection:autowiring] müssen wir die Konstruktorparameter normalerweise nicht angeben, da DI sie erkennt und automatisch übergibt. Es würde also ausreichen, nur den Namen der Klasse anzugeben:

```neon .{file:config/services.neon}
...

services:
	- App\Model\PostFacade
```

Sie brauchen diese Zeile jedoch auch nicht hinzuzufügen. Im Abschnitt `search` am Anfang von `services.neon` ist festgelegt, dass alle Klassen, die auf `-Facade` oder `-Factory` enden, automatisch von DI nachgeschlagen werden, was auch für `PostFacade` gilt.


Zusammenfassung .[#toc-summary]
===============================

Die Klasse `PostFacade` fragt in einem Konstruktor nach `Nette\Database\Explorer` und da diese Klasse im DI-Container registriert ist, erzeugt der Container diese Instanz und übergibt sie. DI erzeugt auf diese Weise eine `PostFacade` Instanz für uns und übergibt sie in einem Konstruktor an die HomePresenter Klasse, die danach gefragt hat. Eine Art Matrjoschka-Puppe des Codes :) Alle Komponenten fordern nur an, was sie brauchen, und es ist ihnen egal, wo und wie es erstellt wird. Die Erstellung wird vom DI-Container übernommen.

.[note]
Hier können Sie mehr über [Dependency Injection |dependency-injection:introduction] und über die [Konfiguration |nette:configuring] lesen.

{{priority: -1}}
{{sitename: Nette Quickstart}}

Modell

Wenn unsere Anwendung wächst, werden wir bald feststellen, dass wir ähnliche Datenbankoperationen an verschiedenen Stellen und in verschiedenen Präsentatoren durchführen müssen, um beispielsweise die neuesten veröffentlichten Artikel zu erfassen. Wenn wir unsere Anwendung verbessern, indem wir den Artikeln eine Markierung hinzufügen, die den Status „in Arbeit“ anzeigt, müssen wir auch alle Standorte in unserer Anwendung durchgehen und eine Where-Klausel hinzufügen, um sicherzustellen, dass nur fertige Artikel ausgewählt werden.

An diesem Punkt wird die direkte Arbeit mit der Datenbank unzureichend, und es wird klüger sein, uns mit einer neuen Funktion zu helfen, die veröffentlichte Artikel zurückgibt. Und wenn wir später eine weitere Klausel hinzufügen (z. B. um keine Artikel mit einem zukünftigen Datum anzuzeigen), müssen wir unseren Code nur an einer Stelle bearbeiten.

Wir platzieren die Funktion in der Klasse PostFacade und nennen sie getPublicArticles().

Wir erstellen unsere Modellklasse PostFacade im Verzeichnis app/Model/, die sich um unsere Artikel kümmert:

<?php
namespace App\Model;

use Nette;

final class PostFacade
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	public function getPublicArticles()
	{
		return $this->database
			->table('posts')
			->where('created_at < ', new \DateTime)
			->order('created_at DESC');
	}
}

In der Klasse übergeben wir die Datenbank Explorer. Damit nutzen wir die Leistungsfähigkeit des DI-Containers.

Wir werden zu HomePresenter wechseln, das wir so bearbeiten, dass wir die Abhängigkeit von Nette\Database\Explorer loswerden und durch eine neue Abhängigkeit von unserer neuen Klasse ersetzen.

<?php
namespace App\UI\Home;

use App\Model\PostFacade;
use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private PostFacade $facade,
	) {
	}

	public function renderDefault(): void
	{
		$this->template->posts = $this->facade
			->getPublicArticles()
			->limit(5);
	}
}

Im Abschnitt use verwenden wir App\Model\PostFacade, so dass wir den PHP-Code auf PostFacade verkürzen können. Wir fordern dieses Objekt im Konstruktor an, schreiben es in die Eigenschaft $facade und verwenden es in der Methode renderDefault.

Der letzte verbleibende Schritt besteht darin, dem DI-Container beizubringen, dieses Objekt zu erzeugen. Dies geschieht in der Regel durch Hinzufügen eines Aufzählungspunkts in der Datei config/services.neon im Abschnitt services, in dem der vollständige Klassenname und die Konstruktorparameter angegeben werden. Dadurch wird es sozusagen registriert, und das Objekt wird dann service genannt. Dank eines Zaubers namens Autowiring müssen wir die Konstruktorparameter normalerweise nicht angeben, da DI sie erkennt und automatisch übergibt. Es würde also ausreichen, nur den Namen der Klasse anzugeben:

...

services:
	- App\Model\PostFacade

Sie brauchen diese Zeile jedoch auch nicht hinzuzufügen. Im Abschnitt search am Anfang von services.neon ist festgelegt, dass alle Klassen, die auf -Facade oder -Factory enden, automatisch von DI nachgeschlagen werden, was auch für PostFacade gilt.

Zusammenfassung

Die Klasse PostFacade fragt in einem Konstruktor nach Nette\Database\Explorer und da diese Klasse im DI-Container registriert ist, erzeugt der Container diese Instanz und übergibt sie. DI erzeugt auf diese Weise eine PostFacade Instanz für uns und übergibt sie in einem Konstruktor an die HomePresenter Klasse, die danach gefragt hat. Eine Art Matrjoschka-Puppe des Codes :) Alle Komponenten fordern nur an, was sie brauchen, und es ist ihnen egal, wo und wie es erstellt wird. Die Erstellung wird vom DI-Container übernommen.

Hier können Sie mehr über Dependency Injection und über die Konfiguration lesen.