Tworzenie aplikacji Medicos Web w Angular (standalone) w Visual Studio 2022
1. Wymagania wstępne
Zanim zaczniesz, upewnij się, że masz:
| Narzędzie | Co robi | Skąd wziąć |
|---|---|---|
| ✅ Node.js (LTS) | środowisko uruchomieniowe JS | nodejs.org |
| ✅ Angular CLI | tworzenie i uruchamianie aplikacji Angular | npm install -g @angular/cli |
| ✅ Visual Studio 2022 | środowisko IDE | visualstudio.microsoft.com |
| ✅ Wtyczka „Node.js development” | do pracy z Angular w VS | Instalator Visual Studio |
➡️ Angular to technologia działająca w przeglądarce. Potrzebuje silnika (Node.js), żeby działać lokalnie.
➡️ Angular CLI to narzędzie, które pozwala jednym poleceniem tworzyć projekty, komponenty, serwisy itd.
➡️ Visual Studio 2022 ma narzędzia do programowania – i musi mieć włączony „Node.js development”, żeby obsłużyć Angulara.
2. Utworzenie projektu Angular w Visual Studio
- Otwórz Visual Studio 2022
- Kliknij: „Utwórz nowy projekt”
- Wyszukaj: Angular i wybierz: „ASP.NET Core with Angular”(niech backend sobie będzie, ale go nie ruszamy)
- Kliknij Dalej
- Nazwij projekt: AngularApps
- Kliknij Utwórz
- Visual Studio utworzy strukturę:
AngularApps/
├─ Controllers/
├─ ClientApp/ to jest nasz Angular
├─ Program.cs
➡️ Ten szablon tworzy dwa projekty naraz:
- backend (ASP.NET) – tu nic nie zmieniamy,
- frontend (Angular) – to jest nasza aplikacja, działa w folderze ClientApp.
Dlatego cała nasza praca będzie w folderze ClientApp.
3. Przejdź do katalogu Angular i uruchom terminal
Angular nie ma żadnego stylu domyślnego. Jeśli chcemy, żeby przyciski wyglądały jak w profesjonalnych aplikacjach, potrzebujemy Bootstrapa – zestawu gotowych styli CSS. Dodaj bootstrapa do angular.json, by formularze wyglądały schludnie i były lepiej dopasowane do różnych ekranów.cd angularapps.client. // dokładną ścieżkę sprawdź sam jak jest u ciebie
Uwaga! może być wymagana komendaSet-ExecutionPolicy RemoteSigned
- W Eksploratorze rozwiązań, kliknij prawym na ClientApp → Otwórz w terminalu
- W terminalu (u dołu Visual Studio) wpisz:
npm install bootstrap
A potem dopisz do pliku angular.json → styles:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
]
➡️ Projekt Angulara ma specjalny plik (package.json), który mówi: „Ta aplikacja potrzebuje takich bibliotek”.
➡️ npm install pobiera i instaluje te biblioteki – bez tego aplikacja nie działa.
To jak instalowanie części do maszyny przed jej złożeniem.
4. Zainicjuj aplikację standalone
W folderze ClientApp, zmień plik main.ts (znajdziesz go w src/) na:
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent)
.catch(err => console.error(err));
Teraz możesz usunąć plik app.module.ts, bo nie będzie już potrzebny.
➡️ W Angularze dawniej wszystko było zarządzane przez plik app.module.ts.
➡️ Ale my korzystamy z nowoczesnego systemu – standalone components, czyli „komponentów samowystarczalnych”.
➡️ Zamiast AppModule, uruchamiamy aplikację przez bootstrapApplication(AppComponent).
Dlatego app.module.ts jest zbędny.
5. Stwórz komponenty
W tym samym terminalu:
ng generate component components/formularz --standalone
ng generate component components/podsumowanie --standalone
Kolejność nie jest kluczowa, ale dobrze zacząć od formularz, bo to on emituje dane do podsumowanie.
➡️ Komponent to część strony – jak „klocek UI”.
➡️ formularz to ekran, na którym wpisujesz dane.
➡️ podsumowanie to ekran z wynikiem.
➡️ –standalone oznacza, że komponent nie potrzebuje modułu (NgModule) i można go używać samodzielnie.
6. Skonfiguruj
app.component.ts
import { Component } from '@angular/core';
import { FormularzComponent } from './components/formularz/formularz.component';
import { PodsumowanieComponent } from './components/podsumowanie/podsumowanie.component';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [
CommonModule,
FormsModule,
FormularzComponent,
PodsumowanieComponent
],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
wynik: any;
zapiszWynik(dane: any) {
this.wynik = dane;
}
}
➡️ AppComponent to kontroler główny całej aplikacji – jak ramka, która spina wszystko razem.
➡️ Gdy użytkownik kliknie „Pokaż dane”, FormularzComponent wysyła dane do AppComponent.
➡️ AppComponent zapisuje je i przekazuje do PodsumowanieComponent.
To centrum przekaźnikowe: odbiera dane z formularza → przekazuje do wyświetlacza.
app.component.html
<h1>Medicos Web</h1>
<app-formularz (wyslij)="zapiszWynik($event)"></app-formularz>
<app-podsumowanie
[bmi]="wynik?.bmi"
[lek]="wynik?.lek"
[godzina]="wynik?.godzina">
</app-podsumowanie>
formularz.component.ts
import { Component, EventEmitter, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-formularz',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './formularz.component.html',
styleUrls: ['./formularz.component.css']
})
export class FormularzComponent {
waga: number = 0;
wzrost: number = 0;
wiek: number = 0;
lek: string = '';
godzina: string = '';
@Output() wyslij = new EventEmitter<any>();
submit() {
const bmi = this.waga / Math.pow(this.wzrost / 100, 2);
this.wyslij.emit({
bmi: bmi.toFixed(2),
lek: this.lek,
godzina: this.godzina
});
}
}
➡️ Formularz to panel, gdzie użytkownik wpisuje dane.
➡️ [ngModel] wiąże dane z polami – Angular sam „zapamiętuje”, co wpisałeś.
➡️ Po kliknięciu przycisku wyliczane jest BMI i emitowany jest obiekt z danymi.
To jak tablica rejestrująca dane wejściowe do maszyny.
formularz.component.html
<div>
<label>Waga (kg): <input [(ngModel)]="waga" type="number"></label><br>
<label>Wzrost (cm): <input [(ngModel)]="wzrost" type="number"></label><br>
<label>Wiek: <input [(ngModel)]="wiek" type="number"></label><br>
<label>Lek: <input [(ngModel)]="lek" type="text"></label><br>
<label>Godzina przyjęcia: <input [(ngModel)]="godzina" type="time"></label><br>
<button (click)="submit()">Pokaż dane</button>
</div>
podsumowanie.component.ts
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-podsumowanie',
standalone: true,
imports: [CommonModule],
templateUrl: './podsumowanie.component.html',
styleUrls: ['./podsumowanie.component.css']
})
export class PodsumowanieComponent {
@Input() bmi: string = '';
@Input() lek: string = '';
@Input() godzina: string = '';
}
➡️ @Input() pozwala przyjąć dane od AppComponent.
➡️ *ngIf=”bmi” – Angular nie wyświetla niczego, dopóki nie ma danych.
➡️ Dane są pokazane dopiero po kliknięciu „Pokaż dane”.
To jak ekran wyników – pokazuje tylko wtedy, gdy coś otrzyma.
podsumowanie.component.html
<div *ngIf="bmi">
<h3>Twoje BMI: {{ bmi }}</h3>
<p>Przypomnienie: Weź lek {{ lek }} o godzinie {{ godzina }}</p>
</div>
Uruchom aplikację
W terminalu wpisz:
ng serve
Wprowadzenie do TypeScript w Angularze (na bazie Medicos)
Co to jest TypeScript?
TypeScript (TS) to nowoczesny język programowania stworzony przez firmę Microsoft.
Jest to rozszerzenie JavaScriptu – dodaje do niego m.in. typowanie, klasy, interfejsy, moduły i podpowiedzi, dzięki czemu programowanie staje się łatwiejsze i bezpieczniejsze.
Porównanie:
- JavaScript – jak zwykły długopis: działa wszędzie, ale nie podpowiada, czy coś robisz dobrze.
- TypeScript – jak długopis z korektorem: podpowiada, ostrzega, pomaga.
Dlaczego TypeScript w Angularze?
Angular to framework, który od początku powstał z myślą o TypeScripcie.
Zalety:
- lepsze błędy (pokazuje błędy zanim uruchomisz aplikację),
- można przewidzieć, jakie dane przepływają przez aplikację,
- każdy plik jest „samowystarczalny” i dobrze opisany,
- idealnie nadaje się do pracy zespołowej i nauki.
Struktura przykładowego pliku TypeScript (komponent Angulara)
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-podsumowanie',
standalone: true,
imports: [CommonModule],
templateUrl: './podsumowanie.component.html',
styleUrls: ['./podsumowanie.component.css']
})
export class PodsumowanieComponent {
@Input() bmi: string = '';
@Input() lek: string = '';
@Input() godzina: string = '';
}
Co oznaczają podstawowe elementy?
| Element | Znaczenie |
|---|---|
import | Pobiera z innego pliku lub biblioteki rzeczy potrzebne w tym pliku |
@Component({ ... }) | Dekorator mówiący: „to jest komponent” |
selector | Jakiego znacznika HTML używać do wyświetlenia komponentu |
standalone: true | Komponent działa samodzielnie bez NgModule |
imports: [...] | Jakie inne biblioteki potrzebuje ten komponent |
export class | Deklaracja klasy komponentu (czyli logika zachowania komponentu) |
@Input() | Pozwala otrzymać dane z zewnętrz (np. od AppComponent) |
@Output() | Pozwala wysyłać dane na zewnątrz (np. do AppComponent) |
EventEmitter<any>() | Narzędzie do emitowania danych na zewnątrz |
ngModel | Dwukierunkowe wiązanie danych (input zna wartość zmiennej i odwrotnie) |
Najczęściej stosowane instrukcje TypeScript w Angularze
1. Deklaracja zmiennej z typem
let wiek: number = 17;
let imie: string = 'Jan';
let aktywny: boolean = true;
2. Tworzenie klasy z właściwościami
export class Uzytkownik {
imie: string = '';
wiek: number = 0;
}
3. Metoda (funkcja) w klasie
submit() {
console.log('Kliknięto przycisk');
}
4. Wysyłanie danych (EventEmitter)
@Output() wyslij = new EventEmitter<any>();
submit() {
this.wyslij.emit({ imie: 'Jan', wiek: 25 });
}
5. Odbieranie danych (@Input)
@Input() imie: string = '';
Jak łatwo to zapamiętać?
„Każdy komponent Angulara to:”
- importy (co potrzebujemy)
- dekorator (mówi Angularowi, że to komponent)
- klasa (logika: co ma się stać, jakie dane ma przechowywać)
A dane mogą:
- przychodzić z zewnątrz przez
@Input() - wychodzić na zewnątrz przez
@Output()iemit()
Praktyczny skrót:
// Formularz wysyła dane:
@Output() wyslij = new EventEmitter<any>();
this.wyslij.emit({ bmi: 22.5 });
// AppComponent odbiera dane:
zapiszWynik(dane) { this.wynik = dane; }
// Podsumowanie pokazuje dane:
@Input() bmi: string = '';
Dzięki TypeScriptowi aplikacja jest:
- czytelniejsza,
- mniej podatna na błędy,
- i bardziej logiczna w przepływie danych – idealna do nauki myślenia obiektowego i komponentowego.
