-
-
Notifications
You must be signed in to change notification settings - Fork 277
Expand file tree
/
Copy pathmodel.texy
More file actions
84 lines (60 loc) · 3.65 KB
/
model.texy
File metadata and controls
84 lines (60 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Model
*****
Ko aplikacija raste, bomo kmalu ugotovili, da na različnih mestih, v različnih presenterjih, potrebujemo izvajati podobne operacije s podatkovno bazo. Na primer pridobivati najnovejše objavljene članke. Ko aplikacijo izboljšamo, na primer tako, da pri člankih dodamo zastavico, ali je osnutek, moramo potem pregledati tudi vsa mesta v aplikaciji, kjer se članki pridobivajo iz podatkovne baze, in dopolniti pogoj where, da se izbirajo samo članki, ki niso osnutki.
V tistem trenutku neposredno delo s podatkovno bazo postane nezadostno in bo bolj priročno, če si pomagamo z novo funkcijo, ki nam bo vračala objavljene članke. In ko kasneje dodamo še en pogoj, na primer da se ne prikazujejo članki z datumom v prihodnosti, uredimo kodo samo na enem mestu.
Funkcijo postavimo na primer v razred `PostFacade` in jo poimenujemo `getPublicArticles()`.
V imeniku `app/Model/` ustvarimo naš modelni razred `PostFacade`, ki nam bo skrbel za članke:
```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');
}
}
```
V razredu si s pomočjo konstruktorja pustimo predati podatkovni Explorer:[api:Nette\Database\Explorer]. Izkoristimo tako moč [DI vsebnika |dependency-injection:passing-dependencies].
Preklopimo na `HomePresenter`, ki ga uredimo tako, da se znebimo odvisnosti od `Nette\Database\Explorer` in jo nadomestimo z novo odvisnostjo od našega novega razreda.
```php .{file:app/Presentation/Home/HomePresenter.php}
<?php
namespace App\Presentation\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);
}
}
```
V sekciji use imamo `App\Model\PostFacade`, tako da lahko zapis v PHP kodi skrajšamo na `PostFacade`. Za ta objekt zaprosimo v konstruktorju, ga zapišemo v lastnost `$facade` in uporabimo v metodi renderDefault.
Ostaja še zadnji korak, in sicer naučiti DI vsebnik ta objekt izdelovati. To se običajno naredi tako, da v datoteko `config/services.neon` v sekcijo `services` dodamo alinejo, navedemo polno ime razreda in parametre konstruktorja. S tem ga tako imenovano registriramo in objekt se potem imenuje **storitev**. Zahvaljujoč čarovniji imenovani [autowiring |dependency-injection:autowiring] nam večinoma ni treba navajati parametrov konstruktorja, ker jih DI sam prepozna in preda. Zadostovalo bi torej navesti samo ime razreda:
```neon .{file:config/services.neon}
...
services:
- App\Model\PostFacade
```
Vendar niti te vrstice ni treba dodajati. V sekciji `search` na začetku `services.neon` je definirano, da vse razrede, ki se končajo z besedo `-Facade` ali `-Factory`, DI poišče sam, kar je tudi primer `PostFacade`.
Povzetek
========
Razred `PostFacade` si v konstruktorju zahteva predajo `Nette\Database\Explorer` in ker je ta razred v DI vsebniku registriran, vsebnik to instanco ustvari in jo preda. DI za nas tako ustvari instanco `PostFacade` in jo preda v konstruktorju razredu HomePresenter, ki je zanjo zaprosil. Nekakšna matrjoška. :) Vsi si samo povedo, kaj želijo, in jih ne zanima, kje se kaj in kako ustvarja. Za ustvarjanje skrbi DI vsebnik.
.[note]
Tukaj si lahko preberete več o [dependency injection |dependency-injection:introduction] in [konfiguraciji |nette:configuring].
{{priority: -1}}