-
Notifications
You must be signed in to change notification settings - Fork 0
Frontend Angular en
- Download Node.js. Download and installation from:
https://nodejs.org/en/
- npm - Package Manager (is available after the installation of node on the command line)
-
Angular/cli. Installation from command line:
npm install -g @angular/cli
-
Json-server. From command line:
npm install -g json-server
-
IDE's, that work with Angular:
Visual Studio Code
Atom
Webstorm
ng new test-app
cd test-app
ng serve
-
The Angular client is a practical tool to create new components, services etc. easily.
-
You can install the Angular client globally on the computer with:
-
npm install -g @angular/cli
-
These are some examples for the most important classes in Angular:
-
Create a service
ng generate service hospital
-
Create a component
ng generate component hospital
-
Create a model
ng generate class hospital --type=model
-
Create a module
ng genarate module hospital
- This documentation shows a good overview:
https://angular.io/docs
The basic blocks of an Angular application are the NgModules, which contain the complication context for the components. The NgModules merge related code into functional sets. The complete application is then a combination of NgModules. Every Angular application has at least one module, the root module, which enables bootstrapping. Typically there are many more modules available.
- Da wir in unserer Applikation nicht sehr viel verschiedene Componenten und Services brauchen haben wir keine zusätzlichen Module erstellt, es gibt jedoch vordefinierte Module, welche wir verwenden
- Unser App-Modul ist fogendermassen aufgebaut:
import {environment} from "../environments/environment";
import {HttpClientModule} from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ApplicationRef } from '@angular/core';
import { FormsModule} from '@angular/forms';
import { CommonModule } from '@angular/common';
import {AppRoutingModule} from "./app-routing.module";
import { AppComponent } from './app.component';
import { MapsComponent } from './components/maps/maps.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { HospitalComponent } from './components/hospital/hospital.component';
import { DropdownComponent } from './components/dropdown/dropdown.component';
import { CharacteristicsComponent } from './components/characteristics/characteristics.component';
import {CharacteristicsService} from './services/characteristics.service';
import {HospitalService} from "./services/hospital.service";
@NgModule({
declarations: [
AppComponent,
MapsComponent,
NavbarComponent,
HospitalComponent,
DropdownComponent,
CharacteristicsComponent
],
imports: [
BrowserModule,
HttpClientModule,
CommonModule,
FormsModule,
AppRoutingModule,
],
providers: [
CharacteristicsService,
HospitalService,
],
bootstrap: [AppComponent]
})
export class AppModule { }
- Die Daten werden über die Services in das Frontend geladen und danach in den dazugehörigen Komponenten aufgerufen.
- Die Services sind dafür da, aus verschiedenen Komponenten auf diese Funktionen/Methoden zugreifen zu können
- Alle Logik, welche nicht direkt mit der View im Zusammenhang steht, werden in Services ausgelagert
- Um die Daten im Service aus dem Backend zu holen wird hier der HttpClient verwendet, welcher auf die gewünschten URL's zugreift, wo sich die JSON befinden
import { HttpClient, HttpHeaders } from '@angular/common/http';
constructor(private http: HttpClient) {
}
- Im Hospital Service holen wir die Spitäler inklusive aller Daten, welche dazugehören (Adresse, Koordinaten, Attribute)
/**
* Gets all hospitals with all corresponding data (address, coordinates, attributes)
* @returns {Observable<Hospital[]>} data in form of the defined model Hospital
*/
getAll(): Observable<Hospital[]> {
return this.http.get<Hospital[]>('https://geopital.herokuapp.com/' + 'api/hospitals')
.map(res => {
return res as Hospital[]
})
}
- Im Characteristics Service laden wir die numerischen und kategoriellen Attribute getrennt um sie für die Attributauswahl bereitstellen zu können
- Die numerischen Attribute bestimmen die Grösse der Punkte
- Die kategoriellen Attribute bestimmen die Form
- Weiterverarbeitung geschieht im Dropdown Component
/**
* Gets all attributes which a hospital can have
* @returns {Observable<Attributes[]>} data in form of the defined model Attributes
*/
getCategoricalAttributes(): Observable<Attributes[]> {
return this.http.get<Attributes[]>('https://geopital.herokuapp.com/' + 'api/attributeTypes')
.map(res => {
return res['attribute_types_string'] as Attributes[];
})
}
getNumericalAttributes(): Observable<Attributes[]> {
return this.http.get<Attributes[]>('https://geopital.herokuapp.com/' + 'api/attributeTypes')
.map(res => {
return res['attribute_types_number'] as Attributes[];
})
}
- Bei den Komponenten wird die Logik implementiert, welche direkt mit der View in Zusammenhang steht
- Zu den Components gehören die TypeScript, HTML und CSS Files
- TypeScript: Für die Logik
- HTML: Für die View
- CSS: Für das Design
- Der Dropdown Component ist der mittlere Teil des rechten Menus
- Im Dropdown Component werden die numerischen und kategoriellen Variablen weiterverarbeitet und in das Auswählfeld auf der rechten Seite des Bildschirmes geladen
/**
* Is called on init and loads the attribute-array from the backend.
* The attributes are stored in two arrays, one that contains all the
* numerical and the other that contains all categorical attributes
* The attributes are then displayed in the html.
*/
ngOnInit() {
this.hospitalService.getCategoricalAttributes()
.subscribe(attributes => {
this.categoricalAttributes = attributes;
});
this.hospitalService.getNumericalAttributes()
.subscribe(attributes => {
this.numericalAttributes = attributes;
});
}
- Im HTML werden dann die Daten auf diese Weise geladen (Beispiel für die kategoriellen Attribute
<!-- first dropdown with categorical attributes -->
<div id="numAttr" class="dropdown" style="padding:5px;">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
1. Attribut:
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" *ngFor="let attribute of categoricalAttributes"
(click)="selectedNumAttribute(attribute)">{{ attribute.nameDE }}</a>
</div>
</div>
- Der Navbarkomponent ist der oberste Teil des Menus auf der rechten Seite
- Hier können die Spitaltypen ausgewählt werden
- Diese Navbar fungiert gleichzeitig als Legende, welche Farbe für welchen Spitaltyp gilt
- Das folgende Beispiel zeigt den Code für die Auswahl des Universitätsspital (die weitere Logik geschieht im MapInitializer, Dokumentation für d3)
/** NavbarComponent.ts */
if (hospitalType == 'K111') {
this.numUniSp = this.numUniSp+1;
updateMap(this.numUniSp, this.numZentSp, this.numGrundVers, this.numPsychKl, this.numRehaKl, this.numSpezKl);
}
<!-- NavbarComponent.html -->
<label class="container">Universitätsspitäler
<input type="checkbox" checked="checked" (change)="selectHospitalType('K111')">
<span class="checkmark1"></span>
</label>
/* NavbarComponent.css */
.checkmark1 {
position: absolute;
top: 0;
left: 0;
height: 25px;
width: 25px;
background-color:#a82a2a;
}
- Im Map Component wird die getAll() Funktion des Hospital Servies aufgerufen um die Spitäler mit allen Attributen zu laden
- Zusätzlich werden aus dem Characteristics Service die numerischen Attribute geladen um die Grösse der Punkte auf der Karte zu bestimmen. Als Default Wert nehmen wir den Ertrag aus medizinischen Leistungen der jeweiligen Spitäler
/**
* Loads all hospital data from backend with the help of hospitalService
* and the Characteristics Service (for the attributes) and gives
* it to the mapDrawer() and setNumAttributes() functions in mapInitializer.js
*/
ngOnInit() {
this.characteristicsService.getNumericalAttributes()
.subscribe(attributes => {
this.numericalAttributes = attributes;
for (let i of this.numericalAttributes) {
if(this.numericalAttributes.code!=null){
if(this.numericalAttributes[i].code=="EtMedL"){
setNumAttribute(this.numericalAttributes[i]);
}
}
}
});
this.hospitalService.getAll()
.subscribe(hospitals => {
this.hospitalsList = hospitals;
mapDrawer(this.hospitalsList);
});
}
- Im MapComponent.html wird die Karte initialisiert, welche im MapInitializer.js erstellt wird
<!-- show map defined in mapInitializer.js on screen -->
<div id="mapid" style="width: 100%; height: 100%; position: absolute"></div>
- Zusätzlich werden im MapComponent.html noch alle Components aufgerufen, welche danach auf der Karte angezeigt werden
<!-- shows navbar on the map -->
<app-navbar></app-navbar>
<!-- shows dropdown on the map -->
<app-dropdown></app-dropdown>
<!-- shows the characteristics on the map -->
<app-characteristics></app-characteristics>
- Der Visualisierungs Teil wird in der Frontend D3 Dokumentation erläutert
Ohne Dokumentation wären wir alle Tiere.