Kurs Angular · Moduł 3: Moduły
NgModules - System Klanowy
W tej lekcji4
W feudalnej Japonii każdy klan (han) miał swoją strukturę, terytorium i zasoby. W Angularze moduły pełnią podobną rolę - grupują powiązane elementy i definiują ich zakres.
Czym są NgModules?
NgModules to kontenery organizacyjne w Angular. Choć od Angular 17+ preferowane są Standalone Components, znajomość modułów jest kluczowa dla:
- Pracy z legacy projektami
- Rozumienia architektury Angular
- Lazy loading (nadal popularny z modułami)
Anatomia NgModule
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
// Komponenty tego modułu
import { SamuraiListComponent } from './samurai-list.component';
import { SamuraiCardComponent } from './samurai-card.component';
import { SamuraiDetailComponent } from './samurai-detail.component';
// Serwisy
import { SamuraiService } from './samurai.service';
@NgModule({
// Komponenty, dyrektywy, pipes NALEŻĄCE do tego modułu
declarations: [
SamuraiListComponent,
SamuraiCardComponent,
SamuraiDetailComponent
],
// Inne moduły, których POTRZEBUJEMY
imports: [
CommonModule, // *ngIf, *ngFor, async pipe, etc.
FormsModule // ngModel, formularze template-driven
],
// Elementy UDOSTĘPNIANE innym modułom
exports: [
SamuraiListComponent,
SamuraiCardComponent
],
// Serwisy dostępne w tym module (legacy sposób)
providers: [
SamuraiService
]
})
export class SamuraiModule { }Uwaga dla Angulara 19 i nowszego: komponenty są domyślnie samodzielne (standalone), a takiego komponentu nie wolno wpisać do declarations - kompilator zgłosi błąd NG6008. Komponent, który ma należeć do NgModule, musi mieć w dekoratorze standalone: false; komponent samodzielny dołączasz do modułu przez imports.
Właściwości Dekoratora @NgModule
| Właściwość | Opis | Przykład |
|---|---|---|
| declarations | Komponenty, dyrektywy, pipes należące do modułu | [MyComponent, MyDirective] |
| imports | Moduły, których potrzebujemy | [CommonModule, FormsModule] |
| exports | Elementy udostępniane na zewnątrz | [MyComponent] |
| providers | Serwisy (legacy, lepiej używać providedIn) | [MyService] |
| bootstrap | Główny komponent (tylko AppModule) | [AppComponent] |
AppModule - Centralny Zamek
// app.module.ts - główny moduł aplikacji
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule, // Wymagany dla aplikacji przeglądarkowych
AppRoutingModule, // Routing
SamuraiModule, // Nasz feature module
DojoModule
],
providers: [],
bootstrap: [AppComponent] // Komponent startowy
})
export class AppModule { }Myśl o module jak o klanie - declarations to wojownicy, którzy do niego należą, imports to sojusze z innymi klanami, exports to siły użyczane na zewnątrz - a AppModule z polem bootstrap jest zamkiem, od którego rusza cała aplikacja.
Kod do tej lekcji: src/app/app.component.ts
import { Component } from '@angular/core';
import { SamuraiModule } from './samurai/samurai.module';
@Component({
selector: 'app-root',
standalone: true,
imports: [SamuraiModule],
template: `
<div class="dojo">
<header>
<h1>Klany i Prowincje</h1>
<p>Moduł 3: Organizacja Kodu w Angular</p>
</header>
<main>
<section class="info-panel">
<h2>Struktura Modułów</h2>
<p>Klany (moduły) organizują wojowników (komponenty) w logiczne grupy.</p>
<ul>
<li>Feature Modules - funkcjonalności</li>
<li>Shared Modules - współdzielone elementy</li>
<li>Core Module - singleton services</li>
</ul>
</section>
<section class="demo-panel">
<h2>Klan Samurajów (Feature Module)</h2>
<app-samurai-list></app-samurai-list>
</section>
</main>
</div>
`,
styles: [`
.dojo {
font-family: 'Segoe UI', sans-serif;
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
min-height: 100vh;
color: #eee;
}
header {
text-align: center;
border-bottom: 2px solid #c9a227;
padding-bottom: 20px;
}
h1 { color: #c9a227; }
h2 { color: #c9a227; }
.info-panel, .demo-panel {
background: rgba(255,255,255,0.05);
border: 1px solid #c9a227;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
}
ul { list-style: none; padding: 0; }
li::before { content: "» "; }
`]
})
export class AppComponent {}Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co umieszczamy w właściwości 'declarations' dekoratora @NgModule?
2. Która właściwość @NgModule wskazuje główny komponent startowy aplikacji i występuje tylko w AppModule?
To 2 z 5 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w poziomie
Ułóż tokeny jednej linii importu dekoratora NgModule z @angular/core:
- Edytor kodu
Uzupełnij dekorator @NgModule dla modułu SamuraiModule z komponentami SamuraiListComponent i SamuraiCardComponent.
- Klikanie w kolejności
Kliknij elementy w kolejności, aby zbudować początek dekoratora: @NgModule({
- Układanie w pionie
Uporządkuj właściwości wewnątrz dekoratora @NgModule zgodnie z typowym zapisem (kolejne linie od góry):