Skip to content

Frontend Angular de

aneahgi edited this page May 22, 2018 · 1 revision

Installation

  • Node.js downloaden. Download und Installation von: https://nodejs.org/en/
  • npm - Package Manager (ist nach der Installation von Node.js dabei, verfügbar auf der Command Line
  • Angular/cli. Installation per Command Line: npm install -g @angular/cli
  • Json-server. Über die Command Line: npm install -g json-server
  • IDE's, welche Angular unterstützen: Visual Studio Code Atom Webstorm

Testen der Umgebung

  • ng new test-app
  • cd test-app
  • ng serve

Angular/cli verwenden

  • Der Angular Client ist ein praktisches Tool um einfach neue Components, Services, Models etc. zu erstellen

  • Der Angular Client wird folgendermassen global auf dem Computer installiert:

  • npm install -g @angular/cli

  • Hier Beispiele für alle wichtigen Arten von Klassen in Angular:

  • ng generate service hospital

  • ng generate component hospital

  • ng generate class hospital --type=model

  • ng genarate module hospital

Allgemeines zu Angular

  • Die Angular Dokumentation gibt einen guten Überblick: https://angular.io/docs

Modules

Die grundlegenden Blöcke einer Angular Applikation sind die NgModules, diese beinhalten den Kompliationskontext für die Komponenten. Die NgModules fügen zusammengehörigen Code in funktionale Sets zusammen. Die komplette Applikation ist dann eine Kombination von NgModules. Jede Angular Applikation hat mindestens ein Modul, das Root Modul, welches das Bootstrapping ermöglicht. Typischerweise sind noch viele weitere Module vorhanden.

  • 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 { }

Daten vom Backend holen und verwenden

  • Die Daten werden über die Services in das Frontend geladen und danach in den dazugehörigen Komponenten aufgerufen.

Services

  • 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) {
}

Hospital Service

  • 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[]
    })
  }

Characteristics Service

  • 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[];
      })
  }

Components

  • 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

Dropdown Component

  • 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>

Navbar Component

  • 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;
}

Map Component

  • 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>

Visualisierung

  • Der Visualisierungs Teil wird in der Frontend D3 Dokumentation erläutert