Frontend Development in 2024 - Gesamt: Unterschied zwischen den Versionen

Aus FernFH MediaWiki
Zur Navigation springen Zur Suche springen
K (Formatierung)
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
<span id="inhalt"></span>
<span id="vorwort"></span>
= Inhalt =
= Vorwort =


[[#vorwort|1 Vorwort [[#vorwort|3]]]]
Es ist 2024. Softwareentwicklung verändert sich gerade in einer Weise wie ich es seit meinem ersten Kontakt mit dieser Disziplin um das Jahr 2010 nicht erlebt habe. ChatBots und KI-gestützte Tools verändern, wie man Softwareprojekte angeht. OpenAIs ChatGPT (OpenAI, 2024) und GitHubs CoPilot (CoPilot, 2024) sind disruptive Technologien, die es Entwickler*innen ermöglichen sich mehr auf die Softwarearchitektur und das große Ganze zu konzentrieren und Unterstützung bei der Detailarbeit zu erhalten.


[[#das-setup|2 Das Setup [[#das-setup|3]]]]
Eines bleibt, wie es immer war: Es gibt nur einen Weg, Programmieren zu lernen, und dieser heißt: selbst zu programmieren. Dieses Studienheft zu lesen, wird niemandem programmieren beibringen. Softwareentwicklung, egal mit welcher Programmiersprache, kann man nur durch Praxis erlernen und vertiefen. Was mich bei Lehrbüchern oft gestört hat, war, dass oft eine Sprache und deren Konzepte erklärt wurden, aber nicht, wie der ganze Prozess von Anfang bis zum Ende funktioniert. Deshalb beginnen wir in diesem Fach mit dem Setup und dem Tooling, welches für ein Frontendprojekt notwendig ist und in der Praxis verwendet wird.


[[#git|2.1 Git [[#git|4]]]]
<span id="das-setup"></span>
= Das Setup =


[[#repository|2.1.1 Repository [[#repository|4]]]]
Bevor wir uns mit JavaScript befassen, richten wir das Entwicklungssetup ein und lernen nützliche Werkzeuge kennen, die das Programmieren erleichtern. Ein lokal laufendes Programm ist zwar gut, kann aber meistens von niemand anderem einfach verwendet werden. Programmieren ist ein Teamsport. Deshalb beginnen wir mit Versionskontrollsystemen, GitHub und der Entwicklungsumgebung. Falls das alles bereits bekannt ist und bereits ein Frontend-Development-Setup vorhanden ist können die nächsten Kapitel überflogen werden und es kann mit der Erstellung des GitHub-Repositories begonnen werden.


[[#commit|2.1.2 Commit [[#commit|4]]]]
<span id="git"></span>
== Git ==


[[#branch|2.1.3 Branch [[#branch|4]]]]
Git (git, 2024) ist ein Versionskontrollsystem (VCS), das die Verwaltung von Quellcode ermöglicht. Es speichert Änderungen an Dateien und erlaubt es, auf frühere Versionen zurückzugreifen. Zuerst gehen wir einige Begriffe durch, und danach werden wir es anwenden und ein GitHub-Repository erstellen. Selbst wenn man allein programmiert, bringt die Verwendung eines VCS Vorteile.


[[#merge|2.1.4 Merge [[#merge|4]]]]
<span id="repository"></span>
=== Repository ===


[[#konflikte|2.1.5 Konflikte [[#konflikte|4]]]]
Ein Repository (Repo) ist ein Speicherort für den Quellcode eines Projekts. Es enthält alle Dateien und Verzeichnisse des Projekts sowie die gesamte Historie der Änderungen.


[[#staging-area|2.1.6 Staging Area [[#staging-area|4]]]]
Lokal: Ein lokales Repository befindet sich auf deinem Computer.


[[#remote-repository|2.1.7 Remote Repository [[#remote-repository|5]]]]
Remote: Ein Remote-Repository befindet sich auf einem Server (z.B. GitHub (GitHub, 2024), GitLab (GitLab, 2024) oder BitBucket (BitBucket, 2024)).


[[#pull-requests-pr-merge-requests-mr|2.1.8 Pull Requests (PR) / Merge Requests (MR) [[#pull-requests-pr-merge-requests-mr|5]]]]
<span id="commit"></span>
=== Commit ===


[[#tags|2.1.9 Tags [[#tags|5]]]]
Ein Commit ist eine gespeicherte Version des Projekts. Jeder Commit hat eine eindeutige ID und enthält eine Nachricht, die die vorgenommenen Änderungen beschreibt.


[[#weiterführende-links|2.1.10 Weiterführende Links [[#weiterführende-links|5]]]]
<code class="mwt-code" >git commit -m </code>&quot;<code class="mwt-code" >Beschreibung der Änderung</code>&quot;


[[#github|2.2 GitHub [[#github|5]]]]
<span id="branch"></span>
===  Branch ===


[[#alles-beginnt-mit-einem-repo|2.2.1 Alles beginnt mit einem Repo [[#alles-beginnt-mit-einem-repo|5]]]]
Ein Branch ist ein unabhängiger Entwicklungszweig innerhalb des Repositories. Der Hauptbranch heißt meist main.


[[#github-und-projektmanagement|2.2.2 GitHub und Projektmanagement [[#github-und-projektmanagement|7]]]]
<code class="mwt-code" >git branch </code>&lt;<code class="mwt-code" >branch-name</code>&gt;


[[#weiterführende-links-1|2.2.3 Weiterführende Links [[#weiterführende-links-1|7]]]]
<span id="merge"></span>
=== Merge ===


[[#frontend-development-aber-richtig---integrierte-entwicklungsumgebungen|2.3 Frontend Development, aber richtig! - Integrierte Entwicklungsumgebungen [[#frontend-development-aber-richtig---integrierte-entwicklungsumgebungen|7]]]]
Merging kombiniert die Änderungen aus einem Branch mit einem anderen. Oft wird ein Feature-Branch in den Hauptbranch gemergt.


[[#visual-studio-code-vscode|2.3.1 Visual Studio Code (VSCode) [[#visual-studio-code-vscode|8]]]]
<code class="mwt-code" >git merge &lt;branch-name&gt;</code>


[[#fallbeispiel-from-peer-review-to-crowd-review|3 Fallbeispiel: From Peer Review to Crowd Review [[#fallbeispiel-from-peer-review-to-crowd-review|11]]]]
<span id="konflikte"></span>


[[#modernes-frontend-development|4 Modernes Frontend Development [[#modernes-frontend-development|12]]]]
=== Konflikte ===


[[#html-html5-für-die-strukturierung-von-webseiten|4.1 HTML, HTML5 für die Strukturierung von Webseiten [[#html-html5-für-die-strukturierung-von-webseiten|13]]]]
Konflikte entstehen, wenn Änderungen in verschiedenen Branches kollidieren. Git kann diese nicht automatisch zusammenführen, sodass eine manuelle Auflösung erforderlich ist.


[[#css-css3-für-das-styling-von-webseiten|4.2 CSS, CSS3 für das Styling von Webseiten [[#css-css3-für-das-styling-von-webseiten|14]]]]
<span id="staging-area"></span>
===  Staging Area ===


[[#css-konstrukte|4.2.1 CSS-Konstrukte [[#css-konstrukte|14]]]]
Die Staging Area ist eine Zwischenschicht zwischen den Dateien im Arbeitsverzeichnis und dem Repository. Änderungen müssen zur Staging Area hinzugefügt werden, bevor sie committet werden.


[[#javascript-syntax-variablen-datentypen-und-operatoren|4.3 JavaScript-Syntax, Variablen, Datentypen und Operatoren [[#javascript-syntax-variablen-datentypen-und-operatoren|17]]]]
<code class="mwt-code" >git add </code>&lt;<code class="mwt-code" >datei-name</code>&gt;


[[#variablen|4.3.1 Variablen [[#variablen|17]]]]
<span id="remote-repository"></span>
=== Remote Repository ===


[[#datentypen|4.3.2 Datentypen [[#datentypen|17]]]]
Ein Remote-Repository ist eine gehostete Version eines Repositories.


[[#operatoren|4.3.1 Operatoren [[#operatoren|17]]]]
* Push''':''' Änderungen von lokal nach remote senden.<p><code class="mwt-code" >git push origin &lt;branch-name&gt;</code></p>


[[#funktionen|4.3.1 Funktionen [[#funktionen|18]]]]
* Pull''':''' Änderungen von remote nach lokal holen.<p><code class="mwt-code" >git pull origin &lt;branch-name&gt;</code></p>


[[#kontrollstrukturen|4.3.2 Kontrollstrukturen [[#kontrollstrukturen|19]]]]
<span id="pull-requests-pr-merge-requests-mr"></span>


[[#objekte-und-arrays|4.3.3 Objekte und Arrays [[#objekte-und-arrays|19]]]]
=== Pull Requests (PR) / Merge Requests (MR) ===


[[#ereignisse|4.3.1 Ereignisse [[#ereignisse|20]]]]
Ein PR oder MR ist eine Anfrage zur Überprüfung und Integration von Änderungen von einem Branch in einen anderen. In der Praxis ist es üblich, dass ein PR von mehreren Entwicklern überprüft wird bevor dieser gemergt wird. In dieser Lehrveranstaltung muss immer ein PR für jede Änderung des Quellcodes erstellt werden.


[[#fehlerbehandlung|4.3.1 Fehlerbehandlung [[#fehlerbehandlung|20]]]]
<span id="tags"></span>
=== Tags ===


[[#module|4.3.1 Module [[#module|21]]]]
Tags sind feste Referenzpunkte im Verlauf eines Projekts. Sie werden oft verwendet, um Versionen zu markieren (z.B.&nbsp;<code class="mwt-code" >v1.0.0</code>).


[[#dom-dom-dom|5 DOM, DOM, DOM [[#dom-dom-dom|21]]]]
<code class="mwt-code" >git tag </code>&lt;<code class="mwt-code" >tag-name</code>&gt;


[[#frameworks|6 Frameworks [[#frameworks|30]]]]
<span id="weiterführende-links"></span>
=== Weiterführende Links ===


[[#react|6.1 React [[#react|30]]]]
* [https://git-scm.com/doc Offizielle Git-Dokumentation]
* [https://git-scm.com/book/en/v2 Pro Git Buch (kostenlos)]


[[#komponenten|6.1.1 Komponenten [[#komponenten|31]]]]
<span id="github"></span>
== GitHub ==


[[#jsx|6.1.2 JSX [[#jsx|31]]]]
GitHub (GitHub, 2024) ist eine web-basierte Plattform, welche Git-Repositories hostet und zusätzliche Funktionen für die Zusammenarbeit und das Projektmanagement bietet. Es wird häufig von Entwicklern verwendet, um Quellcode zu speichern, zu verwalten und gemeinsam zu bearbeiten.


[[#props|6.1.3 Props [[#props|31]]]]
<span id="alles-beginnt-mit-einem-repo"></span>
=== Alles beginnt mit einem Repo ===


[[#state|6.1.4 State [[#state|32]]]]
Gehen wir das Gelernte nun an einem Beispiel durch. Die Erstellung eines Repos in einer der oben genannten Plattformen sollte immer der erste Schritt eines jeden Softwareprojekts sein. In dieser Lehrveranstaltung verwenden wir GitHub.


[[#lifecycle-methoden|6.1.5 Lifecycle-Methoden [[#lifecycle-methoden|32]]]]
Bevor wir beginnen, schauen wir uns an wo wir hinwollen. Ein Repo sollte eine gute “README.md“ Datei haben, welche erklärt wie man das Projekt verwenden kann. .md steht dabei für Markdown (Markdown, 2024). Markdown ist ein Markup-Sprache, die zum Formatieren von Dokumenten verwendet wird. Hier ein paar Beispiele von gut strukturierten Repos und READMEs.


[[#virtual-dom|6.1.6 Virtual DOM [[#virtual-dom|33]]]]
* https://github.com/facebook/react/blob/main/README.md
* https://github.com/angular/angular/blob/main/README.md
* https://github.com/vuejs/vue/blob/main/README.md
Gute READMEs enthalten eine Beschreibung, worum es bei dem Softwareprojekt geht, wie man es verwendet, wie man etwas beisteuern kann sowie Lizenzen. Erstellen wir nun ein GitHub Konto und ein erstes Repo. Falls git noch nicht installiert ist, können wir dieser Anleitung folgen: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git.


[[#event-handling|6.1.7 Event-Handling [[#event-handling|33]]]]
Konto erstellen:


[[#hooks|6.1.8 Hooks [[#hooks|34]]]]
* Gehe zu [https://github.com/ GitHub] und erstelle ein Konto
Ein Repository erstellen:


[[#erste-react-applikation-in-vscode|6.1.9 Erste React Applikation in VSCode [[#erste-react-applikation-in-vscode|34]]]]
* Klicke auf "New" (Neu) oben rechts auf der GitHub-Website
* Gib einen Repository-Namen ein, wähle die Sichtbarkeit (öffentlich oder privat) und füge eine kurze Beschreibung hinzu
* Klicke auf "Create repository"
Git-Repository clonen:


[[#angular|6.2 Angular [[#angular|37]]]]
* Öffne die Git-Bash (unter Windows) oder das Terminal (unter macOS/Linux)
* Klone das Repository von GitHub auf deinen lokalen Computer<p><code class="mwt-code">git clone &lt;Repository-URL&gt;</code></p>


[[#komponenten-1|6.2.1 Komponenten [[#komponenten-1|37]]]]
Ersetze &lt;Repository-URL&gt; durch die URL des erstellten Repositories, welches auf GitHub zu finden ist.


[[#module-1|6.2.2 Module [[#module-1|38]]]]
Dateien hinzufügen und committen:


[[#services|6.2.3 Services [[#services|38]]]]
* Navigiere in das geklonte Verzeichnis:<p><code class="mwt-code">cd &lt;repository-name&gt;</code></p>


[[#routing|6.2.4 Routing [[#routing|39]]]]
* Erstelle eine Datei in dem Verzeichnis und füge die Datei dann zur Staging Area hinzu (beispielsweise eine leere README.md Datei).<p><code class="mwt-code">git add &lt;datei-name&gt;</code></p>


[[#datenbindung|6.2.5 Datenbindung [[#datenbindung|39]]]]
* Commite die Änderungen:<p><code class="mwt-code">git commit -m "Mein erster Commit"</code></p>


[[#forms|6.2.6 Forms [[#forms|40]]]]
Änderungen pushen:


[[#dependency-injection|6.2.7 Dependency Injection [[#dependency-injection|40]]]]
* Sende deine Commits zum Remote-Repository auf GitHub:<p><code class="mwt-code">git push origin &lt;branch-name&gt;</code></p>


[[#mein-erstes-angular-projekt-in-vscode|6.2.8 Mein erstes Angular Projekt in VSCode [[#mein-erstes-angular-projekt-in-vscode|41]]]]
Ersetze &lt;branch-name&gt; durch den Namen deines Branches (z.B. main).


[[#verändere-die-app.component.html|6.2.9 Verändere die app.component.html [[#verändere-die-app.component.html|44]]]]
Pull Requests erstellen:


[[#vue.js|6.3 Vue.js [[#vue.js|44]]]]
Wenn man an einem Projekt mit anderen arbeitest, können folgendermaßen Pull Requests (PR) erstellt werden, um Änderungen vorzuschlagen:


[[#komponenten-2|6.3.1 Komponenten [[#komponenten-2|44]]]]
* Gehe auf GitHub zu deinem Repository
* Klicke auf "Pull requests" und dann auf "New pull request"
* Vergleiche die Änderungen und füge eine Beschreibung hinzu
* Klicke auf "Create pull request"
* Nachdem man einen Pull Request erstellt hast kann dieser gemergt werden


[[#reaktive-datenbindung|6.3.2 Reaktive Datenbindung [[#reaktive-datenbindung|45]]]]
<span id="github-und-projektmanagement"></span>


[[#props-1|6.3.3 Props [[#props-1|46]]]]
=== GitHub und Projektmanagement ===


[[#event-handling-1|6.3.4 Event Handling [[#event-handling-1|46]]]]
GitHub und ähnliche Plattformen geben Entwicklern auch die Möglichkeit Tickets für Teilaufgaben Projektpläne zu erstellen.


[[#vue-router|6.3.5 Vue Router [[#vue-router|47]]]]
<span id="weiterführende-links-1"></span>
=== Weiterführende Links ===


[[#vuex|6.3.6 Vuex [[#vuex|48]]]]
* [https://guides.github.com/ GitHub Guides]: Offizielle Tutorials und Ressourcen von GitHub
* [https://guides.github.com/introduction/flow/ Understanding the GitHub flow]: Den GitHub-Workflow verstehen


[[#mein-erstes-vue.js-projekt-in-vscode|6.3.7 Mein erstes Vue.js Projekt in VSCode [[#mein-erstes-vue.js-projekt-in-vscode|49]]]]
<span id="frontend-development-aber-richtig---integrierte-entwicklungsumgebungen"></span>


[[#asynchrone-programmierung-und-datenübertragung|7 Asynchrone Programmierung und Datenübertragung [[#asynchrone-programmierung-und-datenübertragung|52]]]]
== Frontend Development, aber richtig! - Integrierte Entwicklungsumgebungen ==


[[#asyncawait|7.1 async/await [[#asyncawait|53]]]]
IDEs (Integrated Development Environments) sind umfassende Softwareanwendungen, die Entwicklern Werkzeuge zur Verfügung stellen, um Software zu entwickeln, zu debuggen und zu verwalten. Sie bieten eine integrierte Umgebung, die Folgendes umfasst:


[[#api-definitionen|7.2 API Definitionen [[#api-definitionen|56]]]]
Code Editor: Ein Editor für die Erstellung und Bearbeitung von Quellcode in verschiedenen Programmiersprachen mit Funktionen wie Syntaxhervorhebung und Autovervollständigung.


[[#swagger-ui-verwenden|7.2.1 Swagger UI verwenden [[#swagger-ui-verwenden|56]]]]
Build Automation: Tools zur Automatisierung von Build-Prozessen, die das Kompilieren von Code und das Erstellen von ausführbaren Anwendungen erleichtern.


[[#api-definition-für-unser-fallbeispiel|7.2.2 API Definition für unser Fallbeispiel [[#api-definition-für-unser-fallbeispiel|57]]]]
Debugger: Ein Debugger, der Entwicklern hilft, Fehler im Code zu identifizieren, zu überprüfen und zu beheben.


[[#alternative-tools|7.2.3 Alternative Tools [[#alternative-tools|60]]]]
Version Control Integration: Integration mit Versionskontrollsystemen wie Git, um Codeänderungen zu verwalten und zu synchronisieren.


[[#responsive-webdesign|8 Responsive Webdesign [[#responsive-webdesign|60]]]]
Projektmanagement: Funktionen zur Organisation und Verwaltung von Projekten, einschließlich Datei- und Ordnerstrukturen, Abhängigkeitsverwaltung und Projektvorlagen.


[[#gestaltung-von-benutzeroberflächen-die-auf-verschiedenen-geräten-und-bildschirmgrößen-gut-funktionieren|8.1 Gestaltung von Benutzeroberflächen, die auf verschiedenen Geräten und Bildschirmgrößen gut funktionieren [[#gestaltung-von-benutzeroberflächen-die-auf-verschiedenen-geräten-und-bildschirmgrößen-gut-funktionieren|60]]]]
Code Refactoring: Werkzeuge zur Optimierung und Umstrukturierung des Codes, um ihn lesbarer, effizienter und wartbarer zu machen.


[[#responsive-layout|8.1.1 Responsive Layout [[#responsive-layout|61]]]]
Plugin-Unterstützung: Die Möglichkeit, Funktionalitäten durch Plugins oder Erweiterungen zu erweitern, die spezielle Anforderungen oder Integrationen bieten können.


[[#media-queries|8.1.2 Media Queries [[#media-queries|61]]]]
Beispiele für populäre IDEs sind:


[[#flexible-bilder|8.1.3 Flexible Bilder [[#flexible-bilder|62]]]]
* Visual Studio Code (Microsoft, 2024): Eine leichte und leistungsstarke Code-Editor-IDE von Microsoft, die eine Vielzahl von Sprachen und Plattformen unterstützt.
* IntelliJ IDEA (JetBrains, 2024): Eine Java-IDE von JetBrains, die auch Unterstützung für andere Sprachen bietet und für ihre intelligenten Code-Refactoring-Funktionen bekannt ist.
* Eclipse (Eclipse Foundation, 2024): Eine plattformübergreifende IDE, die ursprünglich für Java entwickelt wurde, aber durch Plugins erweitert werden kann, um andere Sprachen zu unterstützen.
Diese IDEs erleichtern Entwicklern das Arbeiten, indem sie eine zentrale und effiziente Umgebung bieten, um Code zu schreiben, zu testen und zu verwalten.


[[#touchfreundliche-elemente|8.1.4 Touchfreundliche Elemente [[#touchfreundliche-elemente|62]]]]
<span id="visual-studio-code-vscode"></span>
=== Visual Studio Code (VSCode) ===


[[#testen|8.1.5 Testen [[#testen|62]]]]
Entwickler haben oft Präferenzen, wenn es darum geht, welche IDE am intuitivsten ist. Wir werden die Beispiele anhand von VSCode durchgehen.


[[#medienabfragen-und-die-verwendung-von-css-frameworks-zur-unterstützung-des-responsiven-designs|8.2 Medienabfragen und die Verwendung von CSS-Frameworks zur Unterstützung des responsiven Designs [[#medienabfragen-und-die-verwendung-von-css-frameworks-zur-unterstützung-des-responsiven-designs|62]]]]
<span id="visual-studio-code-herunterladen-und-installieren"></span>
==== Visual Studio Code herunterladen und installieren ====


[[#medienabfragen|8.2.1 Medienabfragen [[#medienabfragen|62]]]]
Download''':''' Gehe zur [https://code.visualstudio.com/ VSCode-Website] und lade die Installationsdatei für dein Betriebssystem herunter.


[[#verwendung-von-css-frameworks|8.2.2 Verwendung von CSS-Frameworks [[#verwendung-von-css-frameworks|63]]]]
Installation''':'''


[[#leistungsoptimierung|9 Leistungsoptimierung [[#leistungsoptimierung|64]]]]
* Unter Windows: Öffne die heruntergeladene Datei und folge den Installationsanweisungen
* Unter MacOS: Ziehe die heruntergeladene VSCode-App in deinen Applications-Ordner.
* Unter Linux: Installiere VSCode über den Paketmanager deiner Distribution.


[[#optimierung-von-ladezeiten|9.1 Optimierung von Ladezeiten [[#optimierung-von-ladezeiten|64]]]]
<span id="erweiterungen-installieren"></span>
==== Erweiterungen installieren ====


[[#lazy-loading|9.1.1 Lazy Loading [[#lazy-loading|65]]]]
Man muss sich das Leben nicht zu schwer machen. Es gibt viele nützliche Erweiterungen, die dabei helfen lesbaren, korrekten und effizienten Programmiercode zu schreiben.


[[#caching|9.1.2 Caching [[#caching|65]]]]
Öffne VSCode nach der Installation, um einige nützliche Erweiterungen zu installieren.


[[#minimierung-von-http-anfragen|9.1.3 Minimierung von HTTP-Anfragen [[#minimierung-von-http-anfragen|66]]]]
Gehe zum &quot;Extensions&quot;-Tab (Symbol auf der linken Seitenleiste) und suche nach den folgenden Erweiterungen:


[[#komprimierung|9.1.4 Komprimierung [[#komprimierung|66]]]]
* ESLint (OpenJS Foundation, 2024): Ein Linter für JavaScript, der Syntaxfehler und Best Practices prüft.
* Prettier - Code formatter (Prettier, 2024): Ein Tool zur automatischen Codeformatierung.
Klicke auf &quot;Install&quot;, um die Erweiterungen hinzuzufügen.


[[#optimierung-von-bildern|9.1.5 Optimierung von Bildern [[#optimierung-von-bildern|66]]]]
<span id="hello-world"></span>
==== Hello, World ====


[[#content-delivery-network-cdn|9.1.6 Content Delivery Network (CDN) [[#content-delivery-network-cdn|67]]]]
Erstelle nun einen neuen Ordner auf deinem Computer, um deine JavaScript-Datei zu speichern. Zum Beispiel: hello-world-js.


[[#ressourcenoptimierung|9.2 Ressourcenoptimierung [[#ressourcenoptimierung|67]]]]
* Öffne VS Code
* Gehe zu Datei &gt; Ordner öffnen.. und wähle das zuvor erstellte Verzeichnis hello-world-js aus
* Klicke im Explorer-Fenster von VS Code (links) auf das Symbol ''Neue Datei''.
* Nenne die Datei ''index.html''
* Füge den folgenden HTML-Code in die ''index.html'' Datei ein
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&nbsp; &nbsp;&lt;head&gt;
&nbsp; &nbsp; &nbsp; &lt;meta charset="UTF-8"&gt;
&nbsp; &nbsp; &nbsp; &lt;metaname="viewport"content="width=device-width, initial-scale=1.0"&gt;
&nbsp; &nbsp; &nbsp; &lt;title&gt;Hello World&lt;/title&gt;
&nbsp; &nbsp;&lt;/head&gt;
&nbsp; &nbsp;&lt;body&gt;
&nbsp; &nbsp; &nbsp; &lt;h1&gt;Hello World&lt;/h1&gt;
&nbsp; &nbsp; &nbsp; &lt;script&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// JavaScript Code
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log('Hello, World!');
&nbsp; &nbsp; &nbsp; &lt;/script&gt;
&nbsp; &nbsp;&lt;/body&gt;
&lt;/html&gt;
* Speichere die ''index.html'' Datei (Strg+S oder Datei &gt; Speichern)
* Navigiere zu deinem Projektverzeichnis und öffne die ''index.html'' Datei mit einem Webbrowser (z.B. Chrome, Firefox, Safari)
* Öffne die Entwicklerwerkzeuge des Browsers. In Chrome und Firefox kann man dies mit der rechten Maustaste auf der Seite tun und dann auf „Untersuchen“ oder „Element untersuchen“klicken
* Gehe zum Tab „Konsole”
„Hello, World!“ sollte in der Konsole zu sehen sein


[[#code-splitting|9.2.1 Code-Splitting [[#code-splitting|67]]]]
[[File:media/image1.png|624x361px]]


[[#vermeidung-von-übermäßigem-dom-manipulationen|9.2.2 Vermeidung von übermäßigem DOM-Manipulationen [[#vermeidung-von-übermäßigem-dom-manipulationen|67]]]]
[[File:media/image2.png|624x361px]]


[[#minimierung-von-berechnungen-im-haupt-thread|9.2.3 Minimierung von Berechnungen im Haupt-Thread [[#minimierung-von-berechnungen-im-haupt-thread|68]]]]
<span id="weiterführende-links-2"></span>


[[#ressourcenoptimierung-durch-lazy-loading-von-bildern|9.2.4 Ressourcenoptimierung durch Lazy Loading von Bildern [[#ressourcenoptimierung-durch-lazy-loading-von-bildern|68]]]]
==== Weiterführende Links ====


[[#vermeidung-von-redundanz-bei-netzwerkanfragen|9.2.5 Vermeidung von Redundanz bei Netzwerkanfragen [[#vermeidung-von-redundanz-bei-netzwerkanfragen|68]]]]
* [https://code.visualstudio.com/docs Visual Studio Code Dokumentation]
* [https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint ESLint Extension]
* [https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode Prettier Extension]


[[#effiziente-datenabfragen|9.2.6 Effiziente Datenabfragen [[#effiziente-datenabfragen|69]]]]
<span id="fallbeispiel-from-peer-review-to-crowd-review"></span>
= Fallbeispiel: From Peer Review to Crowd Review =


[[#optimierung-der-bildgröße|9.2.7 Optimierung der Bildgröße [[#optimierung-der-bildgröße|69]]]]
Wir werden die Frontend Development und JavaScript Konzepte anhand eines Fallbeispiels durchgehen. Dieses Beispiel wird sich durch den gesamten Kurs ziehen und die Konzepte werden daran veranschaulicht.


[[#_Toc174479597|10 Bibliography [[#_Toc174479597|69]]]]
Der Peer-Review-Prozess ist entscheidend für die Qualitätssicherung wissenschaftlicher Publikationen. Autoren reichen Manuskripte bei Zeitschriften ein, wo es zunächst von Editoren geprüft wird. Wenn es thematisch und formal passt, wird es an Experten (Gutachter) weitergeleitet. Diese bewerten die Arbeit hinsichtlich ihrer methodischen Korrektheit, Bedeutung, Originalität und Klarheit und erstellen Gutachten mit Empfehlungen zur Akzeptanz, Überarbeitung oder Ablehnung. Die Autoren erhält Feedback, überarbeiten das Manuskript gegebenenfalls und reichen es erneut ein. Nach mehreren Runden von Überarbeitungen und Begutachtungen treffen die Editoren eine endgültige Entscheidung, und die Arbeit wird veröffentlicht. Dieser Prozess ist doppel-blind oder doppel-anonym. Dies bedeutet, dass sowohl die Autoren als auch die Gutachter anonym bleiben. Weder die Autoren wissen, wer die Gutachter sind, noch wissen die Gutachter, wer die Autoren sind. Dies soll sicherstellen, dass die Bewertung der Arbeit objektiv und frei von Vorurteilen erfolgt.


<span id="vorwort"></span>
Dieser Prozess hat mehrere Probleme. Gutachter können unbewusst voreingenommen sein, was zu unfairen Bewertungen führt. Die Anonymität der Begutachtungen kann Verantwortlichkeit verringern und Interessenkonflikte verschleiern. Der Prozess ist oft zeitaufwendig, was die Veröffentlichung verzögert, und die Qualität der Gutachten kann stark variieren. Gutachter sind häufig überlastet, was die Schnelligkeit und Qualität der Begutachtungen beeinträchtigten kann. Zudem besteht ein Publikationsbias zugunsten positiver Ergebnisse, und die hohen Kosten traditioneller Zeitschriften schränken den Zugang zu Forschungsergebnissen ein.
= Vorwort =


Es ist 2024. Softwareentwicklung verändert sich gerade in einer Weise wie ich es seit meinem ersten Kontakt mit dieser Disziplin um das Jahr 2010 nicht erlebt habe. ChatBots und KI-gestützte Tools verändern, wie man Softwareprojekte angeht. OpenAIs ChatGPT (OpenAI, 2024) und GitHubs CoPilot (CoPilot, 2024) sind disruptive Technologien, die es Entwickler*innen ermöglichen sich mehr auf die Softwarearchitektur und das große Ganze zu konzentrieren und Unterstützung bei der Detailarbeit zu erhalten.
Ein Beispiel, welches ich gerne zur Veranschaulichung bringe, ist der Fall von drei MIT-Studenten, die 2015 erfolgreich gefälschte Forschungspapiere bei wissenschaftlichen Zeitschriften einreichten. Diese Papiere, die methodische Fehler und wissenschaftlich unsinnige Inhalte enthielten, wurden von den Gutachtern akzeptiert. Lest euch das Beispiel durch: https://news.mit.edu/2015/how-three-mit-students-fooled-scientific-journals-0414


Eines bleibt, wie es immer war: Es gibt nur einen Weg, Programmieren zu lernen, und dieser heißt: selbst zu programmieren. Dieses Studienheft zu lesen, wird niemandem programmieren beibringen. Softwareentwicklung, egal mit welcher Programmiersprache, kann man nur durch Praxis erlernen und vertiefen. Was mich bei Lehrbüchern oft gestört hat, war, dass oft eine Sprache und deren Konzepte erklärt wurden, aber nicht, wie der ganze Prozess von Anfang bis zum Ende funktioniert. Deshalb beginnen wir in diesem Fach mit dem Setup und dem Tooling, welches für ein Frontendprojekt notwendig ist und in der Praxis verwendet wird.
Stellen wir uns also folgende Anwendung vor: Ein webbasiertes System zur transparenten Veröffentlichung, Begutachtung und Diskussion wissenschaftlicher Publikationen. Sie bietet eine Plattform, auf der Autoren ihre Forschungsarbeiten einreichen, Gutachter diese begutachten und Leser über die veröffentlichten Arbeiten diskutieren können. Der Prozess ist durch verschiedene Rollen (Autor, Gutachter, Leser) und klare Workflow-Schritte strukturiert.


<span id="das-setup"></span>
In so einem System könnte man sich folgendes Datenmodell vorstellen:
= Das Setup =


Bevor wir uns mit JavaScript befassen, richten wir das Entwicklungssetup ein und lernen nützliche Werkzeuge kennen, die das Programmieren erleichtern. Ein lokal laufendes Programm ist zwar gut, kann aber meistens von niemand anderem einfach verwendet werden. Programmieren ist ein Teamsport. Deshalb beginnen wir mit Versionskontrollsystemen, GitHub und der Entwicklungsumgebung. Falls das alles bereits bekannt ist und bereits ein Frontend-Development-Setup vorhanden ist können die nächsten Kapitel überflogen werden und es kann mit der Erstellung des GitHub-Repositories begonnen werden.
Benutzer''':''' Enthält alle Benutzer des Systems und speichert deren Informationen wie Benutzername, E-Mail, Passwort (gehasht) und Rolle (Autor, Gutachter, Leser) ab.


<span id="git"></span>
Publikationen: Speichert Informationen zu den wissenschaftlichen Publikationen wie Titel, Abstract, Inhalt, Autor und den aktuellen Status der Veröffentlichung ab.
== Git ==


Git (git, 2024) ist ein Versionskontrollsystem (VCS), das die Verwaltung von Quellcode ermöglicht. Es speichert Änderungen an Dateien und erlaubt es, auf frühere Versionen zurückzugreifen. Zuerst gehen wir einige Begriffe durch, und danach werden wir es anwenden und ein GitHub-Repository erstellen. Selbst wenn man allein programmiert, bringt die Verwendung eines VCS Vorteile.
Gutachten: Enthält die Gutachten, die von Gutachtern verfasst wurden, und Empfehlung (Akzeptieren, Kleine Überarbeitung, Große Überarbeitung, Ablehnen).


<span id="repository"></span>
Kommentare: Ermöglicht Diskussionen und Kommentare zu den Publikationen durch verschiedene Benutzer.
=== Repository ===


Ein Repository (Repo) ist ein Speicherort für den Quellcode eines Projekts. Es enthält alle Dateien und Verzeichnisse des Projekts sowie die gesamte Historie der Änderungen.
GutachterZuweisungen: Verknüpft Gutachter mit den Publikationen, die sie bewerten sollen.


Lokal: Ein lokales Repository befindet sich auf deinem Computer.
Wir werden in diesem Studienheft Schritt für Schritt die Benutzeroberfläche einer solcher Anwendung erstellen und optimieren.


Remote: Ein Remote-Repository befindet sich auf einem Server (z.B. GitHub (GitHub, 2024), GitLab (GitLab, 2024) oder BitBucket (BitBucket, 2024)).
<span id="modernes-frontend-development"></span>
= Modernes Frontend Development =


<span id="commit"></span>
Beim Start eines Frontend-Projekts beginnt man mit dem Einrichten der Entwicklungsumgebung. Visual Studio Code wird installiert und konfiguriert, um eine effiziente Programmierumgebung zu bieten. Ein GitHub-Repository wird erstellt, um Versionskontrolle zu nutzen, und auf den lokalen Rechner geklont. Das Projekt wird in VSCode geöffnet und es werden hilfreiche Erweiterungen installiert.
=== Commit ===


Ein Commit ist eine gespeicherte Version des Projekts. Jeder Commit hat eine eindeutige ID und enthält eine Nachricht, die die vorgenommenen Änderungen beschreibt.
Der nächste Schritt ist die Planung der Benutzeroberfläche. Wireframes und Mockups werden erstellt, um die Hauptbildschirme der Anwendung zu skizzieren, wie die Startseite, Publikationsübersicht und Detailansichten. Design-Tools wie Figma (Figma, 2024) werden verwendet, um die Benutzeroberflächen und deren Interaktionen detailliert zu entwerfen.


git commit -m &quot;Beschreibung der Änderung&quot;
Für die Application Programming Interface (API)-Definition (auf Deutsch Programmierschnittstelle) werden die benötigten Endpunkte festgelegt, die zur Kommunikation mit dem Server genutzt werden. Eine API-Spezifikation kann beispielsweise mit OpenAPI (OpenAPI, 2024) erstellt werden, die die Endpunkte, Parameter und Rückgabewerte beschreibt. Diese Spezifikation wird in Tools wie Swagger UI (Swagger, 2024) geladen, um eine interaktive Dokumentation zu erstellen und die API zu testen.


<span id="branch"></span>
Abschließend wird ein Frontend-Framework ausgewählt, das den Anforderungen entspricht. Beliebte Optionen wie React (Meta Open Source, 2024), Angular (Google, 2024) oder Vue.js (You, 2024) bieten umfassende Funktionalitäten zur Unterstützung der Anwendung. Das gewählte Framework wird eingerichtet, indem ein neues Projekt erstellt und konfiguriert wird, um die Entwicklungsarbeit zu beginnen.
===  Branch ===


Ein Branch ist ein unabhängiger Entwicklungszweig innerhalb des Repositories. Der Hauptbranch heißt meist main.
JavaScript wird oft geschätzt, weil es vielseitig und zentral für die Webentwicklung ist, mit vielen nützlichen Bibliotheken und ständiger Weiterentwicklung. Die Sprache wird jedoch auch kritisiert wegen seiner Inkonsistenzen, untypisierten Natur und Sicherheitsproblemen, sowie wegen der Komplexität der zahlreichen Frameworks und Tools.


git branch &lt;branch-name&gt;
HTML5, CSS3 und JavaScript arbeiten zusammen, um moderne Webseiten zu gestalten. HTML5 definiert die grundlegende Struktur und den Inhalt der Webseite. CSS3 kümmert sich um das visuelle Design und Layout, wie Farben, Schriftarten und Abstände. JavaScript ermöglicht interaktive und dynamische Funktionen, indem es auf Benutzeraktionen reagiert und Inhalte in Echtzeit aktualisiert. Zusammen bieten diese Technologien die Basis für ansprechende und funktionale Webanwendungen.


<span id="merge"></span>
Dies wäre kein vollständiges Frontend Development Studienheft ohne die Erwähnung von TypeScript (Microsoft, 2024). Wir werden uns auf JavaScript konzentrieren, in der Praxis wird jedoch oft TypeScript anstelle von JavaScript verwendet. Einer der größten Kritikpunkte von JavaScript ist, wie oben erwähnt, die untypisierte Natur. Ein kurzer Ausflug: In untypisierten Sprachen wie JavaScript können Variablen Werte unterschiedlichen Typs annehmen, und Typprüfungen erfolgen erst zur Laufzeit. Das bedeutet, dass Variablen flexibel sind, aber Typfehler erst beim Ausführen des Programms entdeckt werden können. In typisierten Sprachen wie TypeScript, Java oder C#, müssen Typen bereits zur Entwicklungszeit festgelegt werden, was eine frühzeitige Fehlererkennung und strukturierteren Code ermöglicht. Diese Sprachen überprüfen die Typen entweder zur Kompilierzeit oder bei der Programmausführung, was zu robusterem und weniger fehleranfälligem Code führt. Weitere untypisierte Sprachen sind Python, Ruby, PHP und Perl.
=== Merge ===


Merging kombiniert die Änderungen aus einem Branch mit einem anderen. Oft wird ein Feature-Branch in den Hauptbranch gemergt.
TypeScript ist eine Erweiterung von JavaScript, die statische Typisierung bietet, wodurch viele Fehler bereits zur Entwicklungszeit erkannt werden können. JavaScript ist flexibler und wird direkt von Browsern ausgeführt, erfordert jedoch Laufzeitprüfungen für Typfehler. TypeScript bietet zusätzliche Funktionen und eine robustere Entwicklungsumgebung, während JavaScript aufgrund seiner Flexibilität und breiten Unterstützung bevorzugt wird.


git merge &lt;branch-name&gt;
<span id="html-html5-für-die-strukturierung-von-webseiten"></span>
== HTML, HTML5 für die Strukturierung von Webseiten ==


<span id="konflikte"></span>
HTML (Hypertext Markup Language) und HTML5 sind beide Markup-Sprachen zur Strukturierung von Webseiten. HTML5 bringt einige Verbesserungen gegenüber HTML mit sich.
=== Konflikte ===


Konflikte entstehen, wenn Änderungen in verschiedenen Branches kollidieren. Git kann diese nicht automatisch zusammenführen, sodass eine manuelle Auflösung erforderlich ist.
HTML ist die grundlegende Sprache für die Erstellung von Webseiten und definiert, wie Inhalte wie Texte, Links, Bilder und Listen strukturiert werden. Es bietet grundlegende Elemente, die es ermöglichen, einfache und funktionale Webseiten zu erstellen.


<span id="staging-area"></span>
Elemente sind beispielsweise:
===  Staging Area ===


Die Staging Area ist eine Zwischenschicht zwischen den Dateien im Arbeitsverzeichnis und dem Repository. Änderungen müssen zur Staging Area hinzugefügt werden, bevor sie committet werden.
* &lt;h1&gt; bis &lt;h6&gt; für Überschriften
* &lt;p&gt; für Absätze
* &lt;a&gt; für Hyperlinks
* &lt;img&gt; für Bilder
HTML5 ist die neuere Version von HTML und baut auf HTML auf. Es bietet neue semantische Tags wie &lt;header&gt;, &lt;footer&gt;, &lt;section&gt;, und &lt;article&gt;, die helfen, Webseiten besser zu strukturieren und den Inhalt klarer zu gliedern. HTML5 unterstützt auch erweiterte Multimedia-Elemente wie &lt;video&gt; und &lt;audio&gt;, die es einfacher machen, Medieninhalte ohne zusätzliche Plugins einzubinden. Zudem bringt es Verbesserungen bei der Formularverarbeitung und der Unterstützung für moderne Webanwendungen, einschließlich APIs für lokale Speicherung und grafische Darstellungen.


git add &lt;datei-name&gt;
Heutzutage ist HTML5 der Standard für die Webentwicklung.


<span id="remote-repository"></span>
Viel genützte Tags sind:
===  Remote Repository ===


Ein Remote-Repository ist eine gehostete Version eines Repositories.
* &lt;header&gt;: Definiert den Kopfbereich einer Seite oder eines Abschnitts
 
* &lt;nav&gt;: Navigationslinks
* Push''':''' Änderungen von lokal nach remote senden.
* &lt;section&gt;: Markiert thematische Abschnitte innerhalb des Dokuments
* &lt;article&gt;: Stellt eigenständige Inhalte dar, die unabhängig wiederverwendet werden können
* &lt;footer&gt;: Gibt den Fußbereich einer Seite oder eines Abschnitts an
* &lt;aside&gt;: Definiert Inhalte, die nicht direkt zum Hauptinhalt gehören (z.B. Seitenleisten)
* &lt;main&gt;: Markiert den Hauptinhalt der Seite
* &lt;figure&gt; und &lt;figcaption&gt;: Dienen zur Darstellung von Bildern und zugehörigen Beschreibungen
* &lt;video&gt;: Einbetten von Videos
* &lt;audio&gt;: Einbetten von Audiodateien
* &lt;progress&gt;: Zeigt den Fortschritt eines laufenden Prozesses an.
In unserem Beispiel von oben haben wir einige dieser Tags verwendet. Nun fügen wir etwas CSS5 hinzu.


<blockquote>git push origin &lt;branch-name&gt;
<span id="css-css3-für-das-styling-von-webseiten"></span>
</blockquote>
== &nbsp;CSS, CSS3 für das Styling von Webseiten ==
* Pull''':''' Änderungen von remote nach lokal holen.


<blockquote>git pull origin &lt;branch-name&gt;
CSS (Cascading Style Sheets) ist die grundlegende Styling-Sprache für Webseiten. CSS3 ist die aktuelle Version, die erweiterte Funktionen für modernes Layout und Design bietet.
</blockquote>
<span id="pull-requests-pr-merge-requests-mr"></span>
=== Pull Requests (PR) / Merge Requests (MR) ===


Ein PR oder MR ist eine Anfrage zur Überprüfung und Integration von Änderungen von einem Branch in einen anderen. In der Praxis ist es üblich, dass ein PR von mehreren Entwicklern überprüft wird bevor dieser gemergt wird. In dieser Lehrveranstaltung muss immer ein PR für jede Änderung des Quellcodes erstellt werden.
<span id="css-konstrukte"></span>
=== CSS-Konstrukte ===


<span id="tags"></span>
Selektoren: Bestimmen, welche HTML-Elemente gestaltet werden. Beispiel: p für alle Absätze, .class für Elemente mit der Klasse „class“, #id für das Element mit der ID „id“
=== Tags ===


Tags sind feste Referenzpunkte im Verlauf eines Projekts. Sie werden oft verwendet, um Versionen zu markieren (z.B. v1.0.0).
Eigenschaften: Definieren, welche Stile angewendet werden. Beispiel: „color“ für die Textfarbe, „font-size“ für die Schriftgröße


git tag &lt;tag-name&gt;
Werte: Geben die spezifischen Einstellungen für die Eigenschaften an. Beispiel: „color: red“; für rote Textfarbe, „font-size: 16px;“ für eine Schriftgröße von 16 Pixel


<span id="weiterführende-links"></span>
Box-Modell: Beschreibt das Layout von Elementen.
=== Weiterführende Links ===


* [https://git-scm.com/doc Offizielle Git-Dokumentation]
Beispiele:
* [https://git-scm.com/book/en/v2 Pro Git Buch (kostenlos)]


<span id="github"></span>
* „margin: 10px“, für den äußeren Abstand
== GitHub ==
* „border: 1px solid black“ für einen schwarzen Rand, padding: 5px; für den inneren Abstand, width: 100px; für die Breite des Inhaltsbereichs
Positionierung: Bestimmt, wie Elemente auf der Seite angeordnet werden. Beispiel: “position: relative;“ für relative Positionierung, „position: absolute;“ für absolute Positionierung, „top: 10px; left: 20px;“ für die Platzierung des Elements.


GitHub (GitHub, 2024) ist eine web-basierte Plattform, welche Git-Repositories hostet und zusätzliche Funktionen für die Zusammenarbeit und das Projektmanagement bietet. Es wird häufig von Entwicklern verwendet, um Quellcode zu speichern, zu verwalten und gemeinsam zu bearbeiten.
CSS3 führt eine Reihe neuer Konstrukte und Module ein, die das Design und Layout von Webseiten erweitern:


<span id="alles-beginnt-mit-einem-repo"></span>
Flexbox: Ein Layout-Modul für flexible und anpassungsfähige Layouts. Beispiel: display: flex; auf einem Container, um dessen Kinder flexibel zu gestalten.
=== Alles beginnt mit einem Repo ===


Gehen wir das Gelernte nun an einem Beispiel durch. Die Erstellung eines Repos in einer der oben genannten Plattformen sollte immer der erste Schritt eines jeden Softwareprojekts sein. In dieser Lehrveranstaltung verwenden wir GitHub.
Grid Layout: Ermöglicht komplexe, zweidimensionale Layouts mit Zeilen und Spalten. Beispiel: display: grid;für ein Gitter-Layout.


Bevor wir beginnen, schauen wir uns an wo wir hinwollen. Ein Repo sollte eine gute “README.md“ Datei haben, welche erklärt wie man das Projekt verwenden kann. .md steht dabei für Markdown (Markdown, 2024). Markdown ist ein Markup-Sprache, die zum Formatieren von Dokumenten verwendet wird. Hier ein paar Beispiele von gut strukturierten Repos und READMEs.
Media Queries: Passen das Design je nach Bildschirmgröße oder Gerätetyp an. Beispiel: @media (max-width: 600px) { /* Styles für kleine Bildschirme */ }.


* https://github.com/facebook/react/blob/main/README.md
Animationen und Übergänge: Erlauben das Erstellen von dynamischen Effekten. Beispiel: @keyframes für Animationen und transition: all 0.3s ease; für sanfte Übergänge zwischen Zuständen.
* https://github.com/angular/angular/blob/main/README.md
* https://github.com/vuejs/vue/blob/main/README.md


Gute READMEs enthalten eine Beschreibung, worum es bei dem Softwareprojekt geht, wie man es verwendet, wie man etwas beisteuern kann sowie Lizenzen. Erstellen wir nun ein GitHub Konto und erstellen ein erstes Repo. Falls git noch nicht installiert ist, können wir dieser Anleitung folgen: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git.
Transform: Ermöglicht das Skalieren, Drehen oder Verschieben von Elementen. Beispiel: transform: rotate(45deg); zum Drehen eines Elements.


Konto erstellen:
Gradienten: Erstellen von Farbverläufen. Beispiel: background: linear-gradient(to right, red, yellow);für einen Verlauf von Rot nach Gelb.


* Gehe zu [https://github.com/ GitHub] und erstelle ein Konto
Hier das oben erwähnte Beispiel etwas aufgehübscht. Öffnen wir das Beispiel nun wieder in einem Browser und sehen es uns an.<ppre>
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;title&gt;From Peer Review to Crowd Review&lt;/title&gt;
&lt;style&gt;
&nbsp; body {
&nbsp; &nbsp; font-family: Arial, sans-serif;
&nbsp; &nbsp; background: linear-gradient(to right, #342fc9, #2da327);
&nbsp; &nbsp; color: #333;
&nbsp; &nbsp; text-align: center;
&nbsp; &nbsp; margin: 0;
&nbsp; &nbsp; padding: 0;
&nbsp; }
&nbsp; h1 {
&nbsp; &nbsp; color: #007bff;
&nbsp; &nbsp; font-size: 3em;
&nbsp; &nbsp; margin-top: 20vh;
&nbsp; &nbsp; transition: color 0.3s ease;
&nbsp; }
&nbsp; h1:hover {
&nbsp; &nbsp; color: #0056b3;
&nbsp; &nbsp; transform: scale(1.1);
&nbsp; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt; From Peer Review to Crowd Review &lt;/h1&gt;
&lt;script&gt;
// JavaScript Code
console.log('Hello World!');
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;


Ein Repository erstellen:
* CSS3 wurde im &lt;style&gt;-Tag hinzugefügt
* Der Hintergrund der Seite verwendet einen linearen Farbverlauf.
* Der Text der Überschrift &lt;h1&gt; erhält eine Farbe und eine Schriftgröße, und eine Übergangsanimation wird hinzugefügt, die beim Hover-Effekt die Farbe ändert und den Text leicht vergrößert.
[[File:media/image3.png|624x363px]]


* Klicke auf &quot;New&quot; (Neu) oben rechts auf der GitHub-Website
<span id="javascript-syntax-variablen-datentypen-und-operatoren"></span>
* Gib einen Repository-Namen ein, wähle die Sichtbarkeit (öffentlich oder privat) und füge eine kurze Beschreibung hinzu
* Klicke auf &quot;Create repository&quot;


Git-Repository clonen:
== JavaScript-Syntax, Variablen, Datentypen und Operatoren ==


* Öffne die Git-Bash (unter Windows) oder das Terminal (unter macOS/Linux)
Sehen wir uns nun die einzelnen Konstrukte der Sprache JavaScript genauer an.
* Klone das Repository von GitHub auf deinen lokalen Computer


<blockquote>git clone &lt;Repository-URL&gt;
<span id="variablen"></span>
</blockquote>
=== Variablen ===
Ersetze &lt;Repository-URL&gt; durch die URL des erstellten Repositories, welches auf GitHub zu finden ist.


Dateien hinzufügen und committen:
Deklaration''':''' Variablen sind Container zum Speichern von Datenwerten. In JavaScript können sie mit den Schlüsselwörtern var, let und const deklariert werden.


* Navigiere in das geklonte Verzeichnis:
* var: Wird verwendet, um eine Variable mit Funktions-Scope zu deklarieren. Variablen, die mit var deklariert wurden, können innerhalb ihrer Funktion neu deklariert und aktualisiert werden.
* let: Wird verwendet, um eine Variable mit Block-Scope zu deklarieren. Variablen, die mit let deklariert wurden, können innerhalb ihres Blocks aktualisiert, aber nicht neu deklariert werden.
* const: Wird verwendet, um eine Konstante zu deklarieren, die nicht neu zugewiesen werden kann. Konstanten haben ebenfalls Block-Scope.
Beispiele:


<blockquote>cd &lt;repository-name&gt;
<code class="mwt-code" >var alterBenutzername = 'neo_the_one';</code>
</blockquote>
* Erstelle eine Datei in dem Verzeichnis und füge die Datei dann zur Staging Area hinzu (beispielsweise eine leere README.md Datei).


<blockquote>git add &lt;datei-name&gt;
<code class="mwt-code" >let benutzername = 'alice_wonderland';</code>
</blockquote>
* Commite die Änderungen:


<blockquote>git commit -m „Mein erster Commit“
<code class="mwt-code" >const email = 'alice@example.com';</code>
</blockquote>
Änderungen pushen:


* Sende deine Commits zum Remote-Repository auf GitHub:
<code class="mwt-code" >let rolle = 'Autor';</code>


<blockquote>git push origin &lt;branch-name&gt;
<span id="datentypen"></span>
</blockquote>
=== Datentypen ===
Ersetze &lt;branch-name&gt; durch den Namen deines Branches (z.B. main).


Pull Requests erstellen:
Primitive Typen: Dazu gehören Number, String, Boolean, Null, Undefined und Symbol.


Wenn man an einem Projekt mit anderen arbeitest, können folgendermaßen Pull Requests (PR) erstellt werden, um Änderungen vorzuschlagen:
Komplexe Typen: Dazu gehören Objekte und Arrays.


* Gehe auf GitHub zu deinem Repository
Beispiele für primitive Typen sind:
* Klicke auf &quot;Pull requests&quot; und dann auf &quot;New pull request&quot;
* Vergleiche die Änderungen und füge eine Beschreibung hinzu
* Klicke auf &quot;Create pull request&quot;
* Nachdem man einen Pull Request erstellt hast kann dieser gemergt werden


<span id="github-und-projektmanagement"></span>
Number:
=== GitHub und Projektmanagement ===


GitHub und ähnliche Plattformen geben Entwicklern auch die Möglichkeit Tickets für Teilaufgaben Projektpläne zu erstellen.
<code class="mwt-code" >let zahl = 42;</code>


<span id="weiterführende-links-1"></span>
String:
=== Weiterführende Links ===


* [https://guides.github.com/ GitHub Guides]: Offizielle Tutorials und Ressourcen von GitHub
<code class="mwt-code" >let text = </code>&quot;<code class="mwt-code" >Hello World</code>&quot;<code class="mwt-code" >;</code>
* [https://guides.github.com/introduction/flow/ Understanding the GitHub flow]: Den GitHub-Workflow verstehen


<span id="frontend-development-aber-richtig---integrierte-entwicklungsumgebungen"></span>
Boolean:
== Frontend Development, aber richtig! - Integrierte Entwicklungsumgebungen ==


IDEs (Integrated Development Environments) sind umfassende Softwareanwendungen, die Entwicklern Werkzeuge zur Verfügung stellen, um Software zu entwickeln, zu debuggen und zu verwalten. Sie bieten eine integrierte Umgebung, die Folgendes umfasst:
<code class="mwt-code" >let wahrOderFalsch = true;</code>


Code Editor: Ein Editor für die Erstellung und Bearbeitung von Quellcode in verschiedenen Programmiersprachen mit Funktionen wie Syntaxhervorhebung und Autovervollständigung.
Null:


Build Automation: Tools zur Automatisierung von Build-Prozessen, die das Kompilieren von Code und das Erstellen von ausführbaren Anwendungen erleichtern.
<code class="mwt-code" >let leererWert = null;</code>


Debugger: Ein Debugger, der Entwicklern hilft, Fehler im Code zu identifizieren, zu überprüfen und zu beheben.
Undefined:


Version Control Integration: Integration mit Versionskontrollsystemen wie Git, um Codeänderungen zu verwalten und zu synchronisieren.
<code class="mwt-code" >let undefiniert;</code>


Projektmanagement: Funktionen zur Organisation und Verwaltung von Projekten, einschließlich Datei- und Ordnerstrukturen, Abhängigkeitsverwaltung und Projektvorlagen.
Symbol:


Code Refactoring: Werkzeuge zur Optimierung und Umstrukturierung des Codes, um ihn lesbarer, effizienter und wartbarer zu machen.
<code class="mwt-code" >let symbol = Symbol(</code>&quot;<code class="mwt-code" >einzigartig</code>&quot;<code class="mwt-code" >);</code>


Plugin-Unterstützung: Die Möglichkeit, Funktionalitäten durch Plugins oder Erweiterungen zu erweitern, die spezielle Anforderungen oder Integrationen bieten können.
<span id="operatoren"></span>
=== Operatoren ===


Beispiele für populäre IDEs sind:
Vergleichsoperatoren: Werden verwendet, um zwei Werte zu vergleichen. Die gängigen Vergleichsoperatoren sind ==, ===, !=, !==, &lt;, &gt;, &lt;=, &gt;=.


* Visual Studio Code (Microsoft, 2024): Eine leichte und leistungsstarke Code-Editor-IDE von Microsoft, die eine Vielzahl von Sprachen und Plattformen unterstützt.
'''Gleich (==)''': Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 == '42'ergibt true, weil '5' zu 5 konvertiert wird.
* IntelliJ IDEA (JetBrains, 2024): Eine Java-IDE von JetBrains, die auch Unterstützung für andere Sprachen bietet und für ihre intelligenten Code-Refactoring-Funktionen bekannt ist.
* Eclipse (Eclipse Foundation, 2024): Eine plattformübergreifende IDE, die ursprünglich für Java entwickelt wurde, aber durch Plugins erweitert werden kann, um andere Sprachen zu unterstützen.


Diese IDEs erleichtern Entwicklern das Arbeiten, indem sie eine zentrale und effiziente Umgebung bieten, um Code zu schreiben, zu testen und zu verwalten.
'''Strikte Gleichheit (===)''': Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen denselben Typ und Wert haben. Beispiel: 42 === '42' ergibt false, da die Typen unterschiedlich sind.


<span id="visual-studio-code-vscode"></span>
'''Ungleich (!=)''': Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 != '42'ergibt false, da '42' zu 42 konvertiert wird.
=== Visual Studio Code (VSCode) ===


Entwickler haben oft Präferenzen, wenn es darum geht, welche IDE am intuitivsten ist. Wir werden die Beispiele anhand von VSCode durchgehen.
'''Strikte Ungleichheit (!==)''': Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen entweder im Typ oder im Wert unterschiedlich sein. Beispiel: 42 !== '42' ergibt true, da die Typen unterschiedlich sind.


<span id="visual-studio-code-herunterladen-und-installieren"></span>
'''Größer als (&gt;)''': Überprüft, ob der linke Wert größer als der rechte Wert ist. Beispiel: 42 &gt; 23 ergibt true.
==== Visual Studio Code herunterladen und installieren ====


Download''':''' Gehe zur [https://code.visualstudio.com/ VSCode-Website] und lade die Installationsdatei für dein Betriebssystem herunter.
'''Kleiner als (&lt;)''': Überprüft, ob der linke Wert kleiner als der rechte Wert ist. Beispiel: 23 &lt; 42 ergibt true.


Installation''':'''
'''Größer oder gleich (&gt;=)''': Überprüft, ob der linke Wert größer oder gleich dem rechten Wert ist. Beispiel: 42 &gt;= 42 ergibt true, und 42 &gt;= 23 ergibt true.


* Unter Windows: Öffne die heruntergeladene Datei und folge den Installationsanweisungen
'''Kleiner oder gleich (&lt;=)''': Überprüft, ob der linke Wert kleiner oder gleich dem rechten Wert ist. Beispiel: 23 &lt;= 42 ergibt true, und 42 &lt;= 42 ergibt true.
* Unter MacOS: Ziehe die heruntergeladene VSCode-App in deinen Applications-Ordner.
* Unter Linux: Installiere VSCode über den Paketmanager deiner Distribution.


<span id="erweiterungen-installieren"></span>
In unserem Fallbeispiel könnten wir Operatoren beispielsweise folgendermaßen verwenden:<div><div></div></div>
==== Erweiterungen installieren ====
if (publikation.status === 'eingereicht') {
    console.log('Die Publikation wurde eingereicht und wartet auf Begutachtung.');
}


Man muss sich das Leben nicht zu schwer machen. Es gibt viele nützliche Erweiterungen, die dabei helfen lesbaren, korrekten und effizienten Programmiercode zu schreiben.
=== Funktionen ===


Öffne VSCode nach der Installation, um einige nützliche Erweiterungen zu installieren.
'''Funktion''': Ein Block von Code, der entworfen wurde, um eine bestimmte Aufgabe auszuführen. Funktionen können Parameter (Eingaben) annehmen und ein Ergebnis zurückgeben.
function neuerBenutzer(benutzername, email, passwort, rolle) {


Gehe zum &quot;Extensions&quot;-Tab (Symbol auf der linken Seitenleiste) und suche nach den folgenden Erweiterungen:
:return {


* ESLint (OpenJS Foundation, 2024): Ein Linter für JavaScript, der Syntaxfehler und Best Practices prüft.
:benutzername: benutzername,
* Prettier - Code formatter (Prettier, 2024): Ein Tool zur automatischen Codeformatierung.


Klicke auf &quot;Install&quot;, um die Erweiterungen hinzuzufügen.
:email: email,


<span id="hello-world"></span>
:passwort: passwort,
==== Hello, World ====


Erstelle nun einen neuen Ordner auf deinem Computer, um deine JavaScript-Datei zu speichern. Zum Beispiel: hello-world-js.
:rolle: rolle
};


* Öffne VS Code
}
* Gehe zu Datei &gt; Ordner öffnen.. und wähle das zuvor erstellte Verzeichnis hello-world-js aus
let neuerAutor = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password2', 'Autor');
* Klicke im Explorer-Fenster von VS Code (links) auf das Symbol ''Neue Datei''.
* Nenne die Datei ''index.html''
* Füge den folgenden HTML-Code in die ''index.html'' Datei ein


&lt;!DOCTYPE html&gt;
<span id="kontrollstrukturen"></span>


&lt;html lang=&quot;en&quot;&gt;
=== Kontrollstrukturen ===


&lt;head&gt;
'''Bedingte Anweisungen''': Dazu gehören if, else if und else, die verwendet werden, um Code basierend auf spezifischen Bedingungen auszuführen.


&lt;meta charset=&quot;UTF-8&quot;&gt;
'''Schleifen''': Dazu gehören for, while und do...while, die verwendet werden, um Codeblöcke wiederholt auszuführen.
<code class="mwt-code">if (neuerAutor.rolle === 'Autor') {</code>


&lt;metaname=&quot;viewport&quot;content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
<code class="mwt-code">  console.log('Willkommen, Autor!');</code>


&lt;title&gt;Hello World&lt;/title&gt;
<code class="mwt-code">}</code>


&lt;/head&gt;
<code class="mwt-code">let gutachtenListe = [</code>


&lt;body&gt;
<code class="mwt-code">{ empfehlung: 'Akzeptieren', kommentar: 'Sehr gute Arbeit.' },</code>


&lt;h1&gt;Hello World&lt;/h1&gt;
<code class="mwt-code">{ empfehlung: 'Kleine Überarbeitung', kommentar: 'Einige kleine Korrekturen erforderlich.' }</code>


&lt;script&gt;
<code class="mwt-code">];</code>


<blockquote>// JavaScript Code
<code class="mwt-code">for (let i = 0; i </code>&lt;<code class="mwt-code"> gutachtenListe.length; i++) {</code>


console.log('Hello, World!');
<code class="mwt-code">  console.log(gutachtenListe[i].empfehlung);</code>
</blockquote>
&lt;/script&gt;


&lt;/body&gt;
<code class="mwt-code">}</code>


&lt;/html&gt;
<span id="objekte-und-arrays"></span>


* Speichere die ''index.html'' Datei (Strg+S oder Datei &gt; Speichern)
=== Objekte und Arrays ===
* Navigiere zu deinem Projektverzeichnis und öffne die ''index.html'' Datei mit einem Webbrowser (z.B. Chrome, Firefox, Safari)
* Öffne die Entwicklerwerkzeuge des Browsers. In Chrome und Firefox kann man dies mit der rechten Maustaste auf der Seite tun und dann auf „Untersuchen“ oder „Element untersuchen“klicken
* Gehe zum Tab „Konsole”


„Hello, World!“ sollte in der Konsole zu sehen sein
'''Objekte''': Sammlungen von Schlüssel-Wert-Paaren, wobei die Schlüssel Zeichenketten oder Symbole und die Werte beliebige Datentypen sein können.


[[File:media/image1.png|624x361px]]
'''Arrays''': Geordnete Listen von Werten, auf die über ihren Index zugegriffen wird.


[[File:media/image2.png|624x361px]]
Beispiel einen Objektes:


<span id="weiterführende-links-2"></span>
<code class="mwt-code">let kommentar = {</code>
==== Weiterführende Links ====


* [https://code.visualstudio.com/docs Visual Studio Code Dokumentation]
<code class="mwt-code">  benutzername: 'neo_the_one',</code>
* [https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint ESLint Extension]
* [https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode Prettier Extension]


<span id="fallbeispiel-from-peer-review-to-crowd-review"></span>
<code class="mwt-code">   kommentar: 'Sehr interessante Publikation!',</code>
= Fallbeispiel: From Peer Review to Crowd Review =


Wir werden die Frontend Development und JavaScript Konzepte anhand eines Fallbeispiels durchgehen. Dieses Beispiel wird sich durch den gesamten Kurs ziehen und die Konzepte werden daran veranschaulicht.
<code class="mwt-code">  datum: '2024-08-10'</code>


Der Peer-Review-Prozess ist entscheidend für die Qualitätssicherung wissenschaftlicher Publikationen. Autoren reichen Manuskripte bei Zeitschriften ein, wo es zunächst von Editoren geprüft wird. Wenn es thematisch und formal passt, wird es an Experten (Gutachter) weitergeleitet. Diese bewerten die Arbeit hinsichtlich ihrer methodischen Korrektheit, Bedeutung, Originalität und Klarheit und erstellen Gutachten mit Empfehlungen zur Akzeptanz, Überarbeitung oder Ablehnung. Die Autoren erhält Feedback, überarbeiten das Manuskript gegebenenfalls und reichen es erneut ein. Nach mehreren Runden von Überarbeitungen und Begutachtungen treffen die Editoren eine endgültige Entscheidung, und die Arbeit wird veröffentlicht. Dieser Prozess ist doppel-blind oder doppel-anonym. Dies bedeutet, dass sowohl die Autoren als auch die Gutachter anonym bleiben. Weder die Autoren wissen, wer die Gutachter sind, noch wissen die Gutachter, wer die Autoren sind. Dies soll sicherstellen, dass die Bewertung der Arbeit objektiv und frei von Vorurteilen erfolgt.
<code class="mwt-code">};</code>


Dieser Prozess hat mehrere Probleme. Gutachter können unbewusst voreingenommen sein, was zu unfairen Bewertungen führt. Die Anonymität der Begutachtungen kann Verantwortlichkeit verringern und Interessenkonflikte verschleiern. Der Prozess ist oft zeitaufwendig, was die Veröffentlichung verzögert, und die Qualität der Gutachten kann stark variieren. Gutachter sind häufig überlastet, was die Schnelligkeit und Qualität der Begutachtungen beeinträchtigten kann. Zudem besteht ein Publikationsbias zugunsten positiver Ergebnisse, und die hohen Kosten traditioneller Zeitschriften schränken den Zugang zu Forschungsergebnissen ein.
Beispiel eines Arrays:


Ein Beispiel, welches ich gerne zur Veranschaulichung bringe, ist der Fall von drei MIT-Studenten, die 2015 erfolgreich gefälschte Forschungspapiere bei wissenschaftlichen Zeitschriften einreichten. Diese Papiere, die methodische Fehler und wissenschaftlich unsinnige Inhalte enthielten, wurden von den Gutachtern akzeptiert. Lest euch das Beispiel durch: https://news.mit.edu/2015/how-three-mit-students-fooled-scientific-journals-0414
<code class="mwt-code">let wissenschaftlichePublikationen = [</code>"<code class="mwt-code">Deep Learning in AI</code>"<code class="mwt-code">, </code>"<code class="mwt-code">Quantum Computing Advances</code>"<code class="mwt-code">, </code>"<code class="mwt-code">Blockchain Technology Overview</code>"<code class="mwt-code">, </code>"<code class="mwt-code">Genomics and CRISPR</code>"<code class="mwt-code">, </code>"<code class="mwt-code">Sustainable Energy Solutions</code>"<code class="mwt-code">];</code>


Stellen wir uns also folgende Anwendung vor: Ein webbasiertes System zur transparenten Veröffentlichung, Begutachtung und Diskussion wissenschaftlicher Publikationen. Sie bietet eine Plattform, auf der Autoren ihre Forschungsarbeiten einreichen, Gutachter diese begutachten und Leser über die veröffentlichten Arbeiten diskutieren können. Der Prozess ist durch verschiedene Rollen (Autor, Gutachter, Leser) und klare Workflow-Schritte strukturiert.
In JavaScript greift man auf einzelne Elemente folgendermaßen zu:


In so einem System könnte man sich folgendes Datenmodell vorstellen:
<code class="mwt-code">let erstePublikation = wissenschaftlichePublikationen[0];</code>


Benutzer''':''' Enthält alle Benutzer des Systems und speichert deren Informationen wie Benutzername, E-Mail, Passwort (gehasht) und Rolle (Autor, Gutachter, Leser) ab.
In diesem Fall ist erstePublikation gleich "Deep Learning in AI".


Publikationen: Speichert Informationen zu den wissenschaftlichen Publikationen wie Titel, Abstract, Inhalt, Autor und den aktuellen Status der Veröffentlichung ab.
JavaScript-Arrays sind etwas flexibler als Arrays in anderen Programmiersprachen. Sie sind dynamisch und können wachsen oder schrumpfen, ohne eine feste Größe zu haben. Sie erlauben auch das Speichern von Elementen unterschiedlicher Typen, wie Zahlen, Strings und Objekte. Das macht sie flexibler im Vergleich zu Arrays in Sprachen wie Java, die eine feste Größe haben und nur Elemente eines einzigen Datentyps enthalten können. Zudem bieten JavaScript-Arrays zahlreiche eingebaute Methoden zur Manipulation von Daten, wie push, pop und shift, was sie vielseitiger und einfacher zu handhaben macht.


Gutachten: Enthält die Gutachten, die von Gutachtern verfasst wurden, und Empfehlung (Akzeptieren, Kleine Überarbeitung, Große Überarbeitung, Ablehnen).
<span id="ereignisse"></span>


Kommentare: Ermöglicht Diskussionen und Kommentare zu den Publikationen durch verschiedene Benutzer.
=== Ereignisse ===


GutachterZuweisungen: Verknüpft Gutachter mit den Publikationen, die sie bewerten sollen.
'''Ereignis''': Eine Aktion welche im System erkannt und darauf reagiert wird. Beispiele sind Mausklicks, Tastatureingaben oder das Laden einer Seite.


Wir werden in diesem Studienheft Schritt für Schritt die Benutzeroberfläche einer solcher Anwendung erstellen und optimieren.
Mausklick:


<span id="modernes-frontend-development"></span>
<code class="mwt-code" >document.getElementById(</code>&quot;<code class="mwt-code" >zeigePublikation</code>&quot;<code class="mwt-code" >).addEventListener(</code>&quot;<code class="mwt-code" >click</code>&quot;<code class="mwt-code" >, function() {</code>
= Modernes Frontend Development =


Beim Start eines Frontend-Projekts beginnt man mit dem Einrichten der Entwicklungsumgebung. Visual Studio Code wird installiert und konfiguriert, um eine effiziente Programmierumgebung zu bieten. Ein GitHub-Repository wird erstellt, um Versionskontrolle zu nutzen, und auf den lokalen Rechner geklont. Das Projekt wird in VSCode geöffnet und es werden hilfreiche Erweiterungen installiert.
<code class="mwt-code" >alert(</code>&quot;<code class="mwt-code" >Publikation: Deep Learning in AI</code>&quot;<code class="mwt-code" >);</code>


Der nächste Schritt ist die Planung der Benutzeroberfläche. Wireframes und Mockups werden erstellt, um die Hauptbildschirme der Anwendung zu skizzieren, wie die Startseite, Publikationsübersicht und Detailansichten. Design-Tools wie Figma (Figma, 2024) werden verwendet, um die Benutzeroberflächen und deren Interaktionen detailliert zu entwerfen.
<code class="mwt-code" >});</code>


Für die Application Programming Interface (API)-Definition (auf Deutsch Programmierschnittstelle) werden die benötigten Endpunkte festgelegt, die zur Kommunikation mit dem Server genutzt werden. Eine API-Spezifikation kann beispielsweise mit OpenAPI (OpenAPI, 2024) erstellt werden, die die Endpunkte, Parameter und Rückgabewerte beschreibt. Diese Spezifikation wird in Tools wie Swagger UI (Swagger, 2024) geladen, um eine interaktive Dokumentation zu erstellen und die API zu testen.
Mouseover (Maus über ein Element bewegen):


Abschließend wird ein Frontend-Framework ausgewählt, das den Anforderungen entspricht. Beliebte Optionen wie React (Meta Open Source, 2024), Angular (Google, 2024) oder Vue.js (You, 2024) bieten umfassende Funktionalitäten zur Unterstützung der Anwendung. Das gewählte Framework wird eingerichtet, indem ein neues Projekt erstellt und konfiguriert wird, um die Entwicklungsarbeit zu beginnen.
<code class="mwt-code" >document.getElementById(</code>&quot;<code class="mwt-code" >zeigePublikation</code>&quot;<code class="mwt-code" >).addEventListener(</code>&quot;<code class="mwt-code" >mouseover</code>&quot;<code class="mwt-code" >, function() {</code>


JavaScript wird oft geschätzt, weil es vielseitig und zentral für die Webentwicklung ist, mit vielen nützlichen Bibliotheken und ständiger Weiterentwicklung. Die Sprache wird jedoch auch kritisiert wegen seiner Inkonsistenzen, untypisierten Natur und Sicherheitsproblemen, sowie wegen der Komplexität der zahlreichen Frameworks und Tools.
<code class="mwt-code" >console.log(</code>&quot;<code class="mwt-code" >Maus ist über dem Publikationsbereich!</code>&quot;<code class="mwt-code" >);</code>


HTML5, CSS3 und JavaScript arbeiten zusammen, um moderne Webseiten zu gestalten. HTML5 definiert die grundlegende Struktur und den Inhalt der Webseite. CSS3 kümmert sich um das visuelle Design und Layout, wie Farben, Schriftarten und Abstände. JavaScript ermöglicht interaktive und dynamische Funktionen, indem es auf Benutzeraktionen reagiert und Inhalte in Echtzeit aktualisiert. Zusammen bieten diese Technologien die Basis für ansprechende und funktionale Webanwendungen.
<code class="mwt-code" >});</code>


Dies wäre kein vollständiges Frontend Development Studienheft ohne die Erwähnung von TypeScript (Microsoft, 2024). Wir werden uns auf JavaScript konzentrieren, in der Praxis wird jedoch oft TypeScript anstelle von JavaScript verwendet. Einer der größten Kritikpunkte von JavaScript ist, wie oben erwähnt, die untypisierte Natur. Ein kurzer Ausflug: In untypisierten Sprachen wie JavaScript können Variablen Werte unterschiedlichen Typs annehmen, und Typprüfungen erfolgen erst zur Laufzeit. Das bedeutet, dass Variablen flexibel sind, aber Typfehler erst beim Ausführen des Programms entdeckt werden können. In typisierten Sprachen wie TypeScript, Java oder C#, müssen Typen bereits zur Entwicklungszeit festgelegt werden, was eine frühzeitige Fehlererkennung und strukturierteren Code ermöglicht. Diese Sprachen überprüfen die Typen entweder zur Kompilierzeit oder bei der Programmausführung, was zu robusterem und weniger fehleranfälligem Code führt. Weitere untypisierte Sprachen sind Python, Ruby, PHP und Perl.
Keydown (Tastendruck):


TypeScript ist eine Erweiterung von JavaScript, die statische Typisierung bietet, wodurch viele Fehler bereits zur Entwicklungszeit erkannt werden können. JavaScript ist flexibler und wird direkt von Browsern ausgeführt, erfordert jedoch Laufzeitprüfungen für Typfehler. TypeScript bietet zusätzliche Funktionen und eine robustere Entwicklungsumgebung, während JavaScript aufgrund seiner Flexibilität und breiten Unterstützung bevorzugt wird.
<code class="mwt-code" >document.addEventListener(</code>&quot;<code class="mwt-code" >keydown</code>&quot;<code class="mwt-code" >, function(event) {</code>


<span id="html-html5-für-die-strukturierung-von-webseiten"></span>
<code class="mwt-code" >console.log(</code>&quot;<code class="mwt-code" >Gedrückte Taste: </code>&quot;<code class="mwt-code" > + event.key);</code>
== HTML, HTML5 für die Strukturierung von Webseiten ==


HTML (Hypertext Markup Language) und HTML5 sind beide Markup-Sprachen zur Strukturierung von Webseiten. HTML5 bringt einige Verbesserungen gegenüber HTML mit sich.
<code class="mwt-code" >});</code>


HTML ist die grundlegende Sprache für die Erstellung von Webseiten und definiert, wie Inhalte wie Texte, Links, Bilder und Listen strukturiert werden. Es bietet grundlegende Elemente, die es ermöglichen, einfache und funktionale Webseiten zu erstellen.
Seitenladen (DOMContentLoaded):


Elemente sind beispielsweise:
<code class="mwt-code" >document.addEventListener(</code>&quot;<code class="mwt-code" >DOMContentLoaded</code>&quot;<code class="mwt-code" >, function() {</code>


* &lt;h1&gt; bis &lt;h6&gt; für Überschriften
<code class="mwt-code" >console.log(</code>&quot;<code class="mwt-code" >Die Seite ist vollständig geladen!</code>&quot;<code class="mwt-code" >);</code>
* &lt;p&gt; für Absätze
* &lt;a&gt; für Hyperlinks
* &lt;img&gt; für Bilder


HTML5 ist die neuere Version von HTML und baut auf HTML auf. Es bietet neue semantische Tags wie &lt;header&gt;, &lt;footer&gt;, &lt;section&gt;, und &lt;article&gt;, die helfen, Webseiten besser zu strukturieren und den Inhalt klarer zu gliedern. HTML5 unterstützt auch erweiterte Multimedia-Elemente wie &lt;video&gt; und &lt;audio&gt;, die es einfacher machen, Medieninhalte ohne zusätzliche Plugins einzubinden. Zudem bringt es Verbesserungen bei der Formularverarbeitung und der Unterstützung für moderne Webanwendungen, einschließlich APIs für lokale Speicherung und grafische Darstellungen.
<code class="mwt-code" >});</code>


Heutzutage ist HTML5 der Standard für die Webentwicklung.
Formular absenden:


Viel genützte Tags sind:
<code class="mwt-code" >document.getElementById(</code>&quot;<code class="mwt-code" >publikationsFormular</code>&quot;<code class="mwt-code" >).addEventListener(</code>&quot;<code class="mwt-code" >submit</code>&quot;<code class="mwt-code" >, function(event) {</code>


* &lt;header&gt;: Definiert den Kopfbereich einer Seite oder eines Abschnitts
<code class="mwt-code" >event.preventDefault(); // Verhindert das Standardverhalten</code>
* &lt;nav&gt;: Navigationslinks
* &lt;section&gt;: Markiert thematische Abschnitte innerhalb des Dokuments
* &lt;article&gt;: Stellt eigenständige Inhalte dar, die unabhängig wiederverwendet werden können
* &lt;footer&gt;: Gibt den Fußbereich einer Seite oder eines Abschnitts an
* &lt;aside&gt;: Definiert Inhalte, die nicht direkt zum Hauptinhalt gehören (z.B. Seitenleisten)
* &lt;main&gt;: Markiert den Hauptinhalt der Seite
* &lt;figure&gt; und &lt;figcaption&gt;: Dienen zur Darstellung von Bildern und zugehörigen Beschreibungen
* &lt;video&gt;: Einbetten von Videos
* &lt;audio&gt;: Einbetten von Audiodateien
* &lt;progress&gt;: Zeigt den Fortschritt eines laufenden Prozesses an.


In unserem Beispiel von oben haben wir einige dieser Tags verwendet. Nun fügen wir etwas CSS5 hinzu.
<code class="mwt-code" >alert(</code>&quot;<code class="mwt-code" >Formular zur Publikation wurde abgesendet!</code>&quot;<code class="mwt-code" >);</code>


<span id="css-css3-für-das-styling-von-webseiten"></span>
<code class="mwt-code" >});</code>
== CSS, CSS3 für das Styling von Webseiten ==


CSS (Cascading Style Sheets) ist die grundlegende Styling-Sprache für Webseiten. CSS3 ist die aktuelle Version, die erweiterte Funktionen für modernes Layout und Design bietet.
<span id="fehlerbehandlung"></span>
=== Fehlerbehandlung ===


<span id="css-konstrukte"></span>
'''Fehlerbehandlung''': Verwendung von try, catch, finally und throw, um Fehler zu erkennen und zu verarbeiten.
=== CSS-Konstrukte ===
try {
let neuerGutachter = neuerBenutzer('alice_wonderland', 'alice@example.com', 'hashed_password3', 'Gutachter');
if (!neuerGutachter.email.includes('@')) {
    throw new Error('Ungültige E-Mail-Adresse');
    }
} catch (error) {
    console.log(error.message); }
<span id="module"></span>


Selektoren: Bestimmen, welche HTML-Elemente gestaltet werden. Beispiel: p für alle Absätze, .class für Elemente mit der Klasse „class“, #id für das Element mit der ID „id“
=== Module ===


Eigenschaften: Definieren, welche Stile angewendet werden. Beispiel: „color“ für die Textfarbe, „font-size“ für die Schriftgröße
'''Module''': Erlauben es, Code in separate Dateien zu unterteilen. Jedes Modul kann Werte oder Funktionen exportieren und in anderen Dateien importieren.
<code class="mwt-code">// benutzer.js
export function neuerBenutzer(benutzername, email, passwort, rolle) {</code>


Werte: Geben die spezifischen Einstellungen für die Eigenschaften an. Beispiel: „color: red“; für rote Textfarbe, „font-size: 16px;“ für eine Schriftgröße von 16 Pixel
<code class="mwt-code">return {</code>


Box-Modell: Beschreibt das Layout von Elementen.
<code class="mwt-code">  benutzername: benutzername,</code>


Beispiele:
<code class="mwt-code">  email: email,</code>


* „margin: 10px“, für den äußeren Abstand
<code class="mwt-code">  passwort: passwort,</code>
* „border: 1px solid black“ für einen schwarzen Rand, padding: 5px; für den inneren Abstand, width: 100px; für die Breite des Inhaltsbereichs


Positionierung: Bestimmt, wie Elemente auf der Seite angeordnet werden. Beispiel: “position: relative;“ für relative Positionierung, „position: absolute;“ für absolute Positionierung, „top: 10px; left: 20px;“ für die Platzierung des Elements.
<code class="mwt-code">  rolle: rolle</code>


CSS3 führt eine Reihe neuer Konstrukte und Module ein, die das Design und Layout von Webseiten erweitern:
<code class="mwt-code">      };</code>


Flexbox: Ein Layout-Modul für flexible und anpassungsfähige Layouts. Beispiel: display: flex; auf einem Container, um dessen Kinder flexibel zu gestalten.
<code class="mwt-code">}</code>


Grid Layout: Ermöglicht komplexe, zweidimensionale Layouts mit Zeilen und Spalten. Beispiel: display: grid;für ein Gitter-Layout.
<code class="mwt-code">// main.js</code>


Media Queries: Passen das Design je nach Bildschirmgröße oder Gerätetyp an. Beispiel: @media (max-width: 600px) { /* Styles für kleine Bildschirme */ }.
<code class="mwt-code">import { neuerBenutzer } from './benutzer.js';</code>


Animationen und Übergänge: Erlauben das Erstellen von dynamischen Effekten. Beispiel: @keyframes für Animationen und transition: all 0.3s ease; für sanfte Übergänge zwischen Zuständen.
<code class="mwt-code">let neuerLeser = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password4', 'Leser');</code>


Transform: Ermöglicht das Skalieren, Drehen oder Verschieben von Elementen. Beispiel: transform: rotate(45deg); zum Drehen eines Elements.
<code class="mwt-code">console.log(neuerLeser);</code>


Gradienten: Erstellen von Farbverläufen. Beispiel: background: linear-gradient(to right, red, yellow);für einen Verlauf von Rot nach Gelb.
<span id="dom-dom-dom"></span>


Hier das oben erwähnte Beispiel etwas aufgehübscht. Öffnen wir das Beispiel nun wieder in einem Browser und sehen es uns an.
= DOM, DOM, DOM =


&lt;!DOCTYPE html&gt;
Der&nbsp;'''Document Object Model (DOM)''' ist eine Programmierschnittstelle für HTML- und XML-Dokumente. Es repräsentiert die Struktur eines Dokuments als eine Baumstruktur, wobei jede HTML- oder XML-Komponente (wie Tags, Attribute und Text) als Knoten dargestellt wird. Mit dem DOM können Sie die Struktur, den Inhalt und das Styling eines Dokuments dynamisch ändern.


&lt;html lang=&quot;en&quot;&gt;
Kommen wir zurück zu unserem Fallbeispiel. Auf unserer Webseite möchten wir Informationen zu Publikationen anzeigen und es den Benutzern ermöglichen, Kommentare zu hinterlassen.


&lt;head&gt;
Ein einfaches HTML-Dokument für unser System könnte wie folgt aussehen:
&lt;<code class="mwt-code">!DOCTYPE html</code>&gt;
&lt;<code class="mwt-code">html lang=</code>"<code class="mwt-code">de</code>"&gt;
&lt;<code class="mwt-code">head</code>&gt;
&lt;<code class="mwt-code">meta charset=</code>"<code class="mwt-code">UTF-8</code>"&gt;


&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;<code class="mwt-code">title</code>&gt;<code class="mwt-code">Publikationen</code>&lt;<code class="mwt-code">/title</code>&gt;


&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;<code class="mwt-code">/head</code>&gt;


&lt;title&gt;From Peer Review to Crowd Review&lt;/title&gt;
&lt;<code class="mwt-code">body</code>&gt;


&lt;style&gt;
&lt;<code class="mwt-code">h1</code>&gt;<code class="mwt-code">Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code">/h1</code>&gt;


body {
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">publikation-container</code>"&gt;


font-family: Arial, sans-serif;
&lt;<code class="mwt-code">h2 id=</code>"<code class="mwt-code">publikation-titel</code>"&gt;<code class="mwt-code">Gibt es die Matrix wirklich?</code>&lt;<code class="mwt-code">/h2</code>&gt;


background: linear-gradient(to right, #342fc9, #2da327);
&lt;<code class="mwt-code">p id=</code>"<code class="mwt-code">publikation-abstract</code>"&gt;<code class="mwt-code">Eine umfassende Analyse der Frage, ob wir in einer simulierten Realität leben.</code>&lt;<code class="mwt-code">/p</code>&gt;


color: #333;
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">kommentare</code>"&gt;


text-align: center;
&lt;<code class="mwt-code">h3</code>&gt;<code class="mwt-code">Kommentare</code>&lt;<code class="mwt-code">/h3</code>&gt;


margin: 0;
&lt;<code class="mwt-code">!-- Kommentare werden hier hinzugefügt --</code>&gt;


padding: 0;
&lt;<code class="mwt-code">/div</code>&gt;


}
&lt;<code class="mwt-code">textarea id=</code>"<code class="mwt-code">neuer-kommentar</code>"<code class="mwt-code"> placeholder=</code>"<code class="mwt-code">Fügen Sie einen Kommentar hinzu...</code>"&gt;&lt;<code class="mwt-code">/textarea</code>&gt;


h1 {
&lt;<code class="mwt-code">button id=</code>"<code class="mwt-code">kommentar-hinzufuegen</code>"&gt;<code class="mwt-code">Kommentar hinzufügen</code>&lt;<code class="mwt-code">/button</code>&gt;


color: #007bff;
&lt;<code class="mwt-code">/div</code>&gt;


font-size: 3em;
&lt;<code class="mwt-code">script src=</code>"<code class="mwt-code">app.js</code>"&gt;&lt;<code class="mwt-code">/script</code>&gt;


margin-top: 20vh;
&lt;<code class="mwt-code">/body</code>&gt;


transition: color 0.3s ease;
&lt;<code class="mwt-code">/html</code>&gt;


}


h1:hover {
[[File:media/image4.png|624x362px]]


color: #0056b3;
In diesem Beispiel haben wir HTML-Elemente wie h1, h2, p, div, textarea und button, die verschiedene Teile unserer Publikationsseite darstellen. Das DOM repräsentiert diese Elemente als Knoten in einem Baum.


transform: scale(1.1);
In unserem JavaScript-Code können wir auf diese DOM-Elemente zugreifen und sie manipulieren. Erstelle in demselben Ordner eine neue Datei app.js. In dieser Datei schreiben wir den JavaScript Code. Auf diesen wird in dem obigen Beispiel mit &lt;script src=“app.js“&gt; zugegriffen. Manipulieren wir nun die HTML Datei mit JavaScript code. Hier sind einige Beispiele:
<code class="mwt-code">// Zugriff auf DOM-Elemente</code>


}
<code class="mwt-code">let titelElement = document.getElementById('publikation-titel');</code>


&lt;/style&gt;
<code class="mwt-code">let abstractElement = document.getElementById('publikation-abstract');</code>


&lt;/head&gt;
<code class="mwt-code">let kommentareElement = document.getElementById('kommentare');</code>


&lt;body&gt;
<code class="mwt-code">let textareaElement = document.getElementById('neuer-kommentar');</code>


&lt;h1&gt; From Peer Review to Crowd Review &lt;/h1&gt;
<code class="mwt-code">let buttonElement = document.getElementById('kommentar-hinzufuegen');</code>


&lt;script&gt;
<code class="mwt-code">// Hinzufügen eines Kommentars</code>


// JavaScript Code
<code class="mwt-code">buttonElement.addEventListener('click', () =</code>&gt;<code class="mwt-code"> {</code>


console.log('Hello World!');
<code class="mwt-code">let neuerKommentar = textareaElement.value;</code>


&lt;/script&gt;
<code class="mwt-code">if (neuerKommentar) {</code>


&lt;/body&gt;
<code class="mwt-code">  let kommentarElement = document.createElement('p');</code>


&lt;/html&gt;
<code class="mwt-code">  kommentarElement.textContent = neuerKommentar;</code>


* CSS3 wurde im &lt;style&gt;-Tag hinzugefügt
<code class="mwt-code">  kommentareElement.appendChild(kommentarElement);</code>
* Der Hintergrund der Seite verwendet einen linearen Farbverlauf.
* Der Text der Überschrift &lt;h1&gt; erhält eine Farbe und eine Schriftgröße, und eine Übergangsanimation wird hinzugefügt, die beim Hover-Effekt die Farbe ändert und den Text leicht vergrößert.


[[File:media/image3.png|624x363px]]
<code class="mwt-code">  textareaElement.value = ''; // Textarea leeren</code>


<span id="javascript-syntax-variablen-datentypen-und-operatoren"></span>
<code class="mwt-code">} else {</code>
== JavaScript-Syntax, Variablen, Datentypen und Operatoren ==


Sehen wir uns nun die einzelnen Konstrukte der Sprache JavaScript genauer an.
<code class="mwt-code">  alert('Bitte geben Sie einen Kommentar ein.');</code>


<span id="variablen"></span>
<code class="mwt-code">}</code>
=== Variablen ===


Deklaration''':''' Variablen sind Container zum Speichern von Datenwerten. In JavaScript können sie mit den Schlüsselwörtern var, let und const deklariert werden.
<code class="mwt-code">});</code>
Öffne die HTML Datei erneut in deinem Browser und siehe was sich verändert hat.


* var: Wird verwendet, um eine Variable mit Funktions-Scope zu deklarieren. Variablen, die mit var deklariert wurden, können innerhalb ihrer Funktion neu deklariert und aktualisiert werden.
[[File:media/image5.png|624x364px]]
* let: Wird verwendet, um eine Variable mit Block-Scope zu deklarieren. Variablen, die mit let deklariert wurden, können innerhalb ihres Blocks aktualisiert, aber nicht neu deklariert werden.
* const: Wird verwendet, um eine Konstante zu deklarieren, die nicht neu zugewiesen werden kann. Konstanten haben ebenfalls Block-Scope.


var alterBenutzername = 'neo_the_one';
[[File:media/image6.png|624x364px]]


let benutzername = 'alice_wonderland';
Im obigen JavaScript-Beispiel verwenden wir das DOM, um:


const email = 'alice@example.com';
* '''Elemente zu finden''': Wir greifen auf Elemente wie den Titel und das Abstract der Publikation zu.
* '''Ereignisse zu behandeln''': Wir fügen einen Event-Listener für den Button hinzu, um einen Kommentar hinzuzufügen, wenn der Button geklickt wird.
* '''Elemente zu erstellen und zu modifizieren''': Wir erstellen neue p-Elemente für Kommentare und fügen sie dem DOM hinzu. Außerdem ändern wir den Inhalt von textarea und leeren ihn nach dem Hinzufügen eines Kommentars.<br>
Die Baumstruktur des DOM für unser Beispiel sieht folgendermaßen aus:
&lt;<code class="mwt-code">html</code>&gt;


let rolle = 'Autor';
&lt;<code class="mwt-code">head</code>&gt;


<span id="datentypen"></span>
&lt;<code class="mwt-code">meta</code>&gt;
=== Datentypen ===


Primitive Typen: Dazu gehören Number, String, Boolean, Null, Undefined und Symbol.
&lt;<code class="mwt-code">title</code>&gt;


Komplexe Typen: Dazu gehören Objekte und Arrays.
&lt;<code class="mwt-code">body</code>&gt;


Beispiele für primitive Typen sind:
&lt;<code class="mwt-code">h1</code>&gt;


Number:
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">publikation-container</code>"&gt;


let zahl = 42;
&lt;<code class="mwt-code">h2 id=</code>"<code class="mwt-code">publikation-titel</code>"&gt;


String:
&lt;<code class="mwt-code">p id=</code>"<code class="mwt-code">publikation-abstract</code>"&gt;


let text = &quot;Hello World&quot;;
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">kommentare</code>"&gt;


Boolean:
&lt;<code class="mwt-code">h3</code>&gt;


let wahrOderFalsch = true;
<code class="mwt-code">(Kommentare werden hier hinzugefügt)</code>


Null:
&lt;<code class="mwt-code">textarea id=</code>"<code class="mwt-code">neuer-kommentar</code>"&gt;


let leererWert = null;
&lt;<code class="mwt-code">button id=</code>"<code class="mwt-code">kommentar-hinzufuegen</code>"&gt;


Undefined:


let undefiniert;
Sehen wir uns nun weitere Beispiele von Ereignissen an.


Symbol:
'''Ereignis: Eingabe in Textarea'''


let symbol = Symbol(&quot;einzigartig&quot;);
'''Beschreibung''': Zeigt eine Live-Vorschau des eingegebenen Kommentars an, während der Benutzer tippt.


<span id="operatoren"></span>
<code class="mwt-code">// Zugriff auf DOM-Elemente</code>
=== Operatoren ===


Vergleichsoperatoren: Werden verwendet, um zwei Werte zu vergleichen. Die gängigen Vergleichsoperatoren sind ==, ===, !=, !==, &lt;, &gt;, &lt;=, &gt;=.
<code class="mwt-code">let textareaElement = document.getElementById('neuer-kommentar');</code>


'''Gleich (==)''': Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 == '42'ergibt true, weil '5' zu 5 konvertiert wird.
<code class="mwt-code">let liveVorschauElement = document.createElement('div');</code>


'''Strikte Gleichheit (===)''': Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen denselben Typ und Wert haben. Beispiel: 42 === '42' ergibt false, da die Typen unterschiedlich sind.
<code class="mwt-code">liveVorschauElement.id = 'live-vorschau';</code>


'''Ungleich (!=)''': Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 != '42'ergibt false, da '42' zu 42 konvertiert wird.
<code class="mwt-code">document.body.appendChild(liveVorschauElement);</code>


'''Strikte Ungleichheit (!==)''': Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen entweder im Typ oder im Wert unterschiedlich sein. Beispiel: 42 !== '42' ergibt true, da die Typen unterschiedlich sind.
<code class="mwt-code">// Ereignis-Handler für die Eingabe in die Textarea</code>


'''Größer als (&gt;)''': Überprüft, ob der linke Wert größer als der rechte Wert ist. Beispiel: 42 &gt; 23 ergibt true.
<code class="mwt-code">textareaElement.addEventListener('input', () =</code>&gt;<code class="mwt-code"> {</code>


'''Kleiner als (&lt;)''': Überprüft, ob der linke Wert kleiner als der rechte Wert ist. Beispiel: 23 &lt; 42 ergibt true.
<code class="mwt-code">let eingabeText = textareaElement.value;</code>


'''Größer oder gleich (&gt;=)''': Überprüft, ob der linke Wert größer oder gleich dem rechten Wert ist. Beispiel: 42 &gt;= 42 ergibt true, und 42 &gt;= 23 ergibt true.
<code class="mwt-code">liveVorschauElement.textContent = `Vorschau: ${eingabeText}`;</code>


'''Kleiner oder gleich (&lt;=)''': Überprüft, ob der linke Wert kleiner oder gleich dem rechten Wert ist. Beispiel: 23 &lt;= 42 ergibt true, und 42 &lt;= 42 ergibt true.
<code class="mwt-code">});</code>


In unserem Fallbeispiel könnten wir Operatoren beispielsweise folgendermaßen verwenden:
[[File:media/image7.png|624x363px]]


if (publikation.status === 'eingereicht') {
'''Ereignis: Mausbewegung'''


console.log('Die Publikation wurde eingereicht und wartet auf Begutachtung.');
'''Beschreibung''': Ändert die Hintergrundfarbe eines Elements, wenn die Maus darüber bewegt wird.


}
<code class="mwt-code">// Zugriff auf DOM-Element</code>


<span id="funktionen"></span>
<code class="mwt-code">let titelElement = document.getElementById('publikation-titel');</code>
=== Funktionen ===


'''Funktion''': Ein Block von Code, der entworfen wurde, um eine bestimmte Aufgabe auszuführen. Funktionen können Parameter (Eingaben) annehmen und ein Ergebnis zurückgeben.
<code class="mwt-code">// Ereignis-Handler für Mausbewegung</code>


function neuerBenutzer(benutzername, email, passwort, rolle) {
<code class="mwt-code">titelElement.addEventListener('mouseover', () =</code>&gt;<code class="mwt-code"> {</code>


return {
<code class="mwt-code">titelElement.style.backgroundColor = '#f0f0f0'; // Hintergrundfarbe ändern</code>


benutzername: benutzername,
<code class="mwt-code">});</code>


email: email,
<code class="mwt-code">// Ereignis-Handler für Mausverlassen</code>


passwort: passwort,
<code class="mwt-code">titelElement.addEventListener('mouseout', () =</code>&gt;<code class="mwt-code"> {</code>


rolle: rolle
<code class="mwt-code">titelElement.style.backgroundColor = ''; // Hintergrundfarbe zurücksetzen</code>


};
<code class="mwt-code">});</code>


}
[[File:media/image8.png|624x360px]]


let neuerAutor = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password2', 'Autor');
'''Ereignis: Formular-Submit'''


<span id="kontrollstrukturen"></span>
'''Beschreibung''': Verhindert das Standard-Submit-Verhalten eines Formulars und zeigt stattdessen eine Bestätigungsmeldung an.
=== Kontrollstrukturen ===


'''Bedingte Anweisungen''': Dazu gehören if, else if und else, die verwendet werden, um Code basierend auf spezifischen Bedingungen auszuführen.
index.html


'''Schleifen''': Dazu gehören for, while und do...while, die verwendet werden, um Codeblöcke wiederholt auszuführen.
&lt;<code class="mwt-code">form id=</code>"<code class="mwt-code">kommentar-form</code>"&gt;


if (neuerAutor.rolle === 'Autor') {
&lt;<code class="mwt-code">textarea id=</code>"<code class="mwt-code">neuer-kommentar</code>"<code class="mwt-code"> placeholder=</code>"<code class="mwt-code">Fuegen Sie einen Kommentar hinzu...</code>"&gt;


console.log('Willkommen, Autor!');
&lt;<code class="mwt-code">/textarea</code>&gt;


}
&lt;<code class="mwt-code">button type=</code>"<code class="mwt-code">submit</code>"<code class="mwt-code"> id=</code>"<code class="mwt-code">kommentar-hinzufuegen</code>"&gt;<code class="mwt-code">Kommentar hinzufuegen</code>


let gutachtenListe = [
&lt;<code class="mwt-code">/button</code>&gt;


{ empfehlung: 'Akzeptieren', kommentar: 'Sehr gute Arbeit.' },
&lt;<code class="mwt-code">/form</code>&gt;


{ empfehlung: 'Kleine Überarbeitung', kommentar: 'Einige kleine Korrekturen erforderlich.' }
&lt;<code class="mwt-code">script src=</code>"<code class="mwt-code">app.js</code>"&gt;&lt;<code class="mwt-code">/script</code>&gt;


];
app.js


for (let i = 0; i &lt; gutachtenListe.length; i++) {
<code class="mwt-code">// Zugriff auf DOM-Elemente</code>


console.log(gutachtenListe[i].empfehlung);
<code class="mwt-code">let textareaElement = document.getElementById('neuer-kommentar');</code>


}
<code class="mwt-code">let formElement = document.getElementById('kommentar-form');</code>


<span id="objekte-und-arrays"></span>
<code class="mwt-code">// Ereignis-Handler für Formular-Submit</code>
=== Objekte und Arrays ===


'''Objekte''': Sammlungen von Schlüssel-Wert-Paaren, wobei die Schlüssel Zeichenketten oder Symbole und die Werte beliebige Datentypen sein können.
<code class="mwt-code">formElement.addEventListener('submit', (event) =</code>&gt;<code class="mwt-code"> {</code>


'''Arrays''': Geordnete Listen von Werten, auf die über ihren Index zugegriffen wird.
<code class="mwt-code">event.preventDefault(); // Verhindert das Standard-Submit-Verhalten</code>


Beispiel einen Objektes:
<code class="mwt-code">let neuerKommentar = textareaElement.value;</code>


let kommentar = {
<code class="mwt-code">if (neuerKommentar) {</code>


benutzername: 'neo_the_one',
<code class="mwt-code">let kommentarElement = document.createElement('p');</code>


kommentar: 'Sehr interessante Publikation!',
<code class="mwt-code">kommentarElement.textContent = neuerKommentar;</code>


datum: '2024-08-10'
<code class="mwt-code">textareaElement.value = ''; // Textarea leeren</code>


};
<code class="mwt-code">alert('Kommentar erfolgreich hinzugefuegt!');</code>


Beispiel eines Arrays:
<code class="mwt-code">} else {</code>


let wissenschaftlichePublikationen = [&quot;Deep Learning in AI&quot;, &quot;Quantum Computing Advances&quot;, &quot;Blockchain Technology Overview&quot;, &quot;Genomics and CRISPR&quot;, &quot;Sustainable Energy Solutions&quot;];
<code class="mwt-code">alert('Bitte geben Sie einen Kommentar ein.');</code>


In JavaScript greift man auf einzelne Elemente folgendermaßen zu:
<code class="mwt-code">}</code>


let erstePublikation = wissenschaftlichePublikationen[0];
<code class="mwt-code">});</code>


In diesem Fall ist erstePublikation gleich &quot;Deep Learning in AI&quot;.
[[File:media/image9.png|624x361px]]


JavaScript-Arrays sind etwas flexibler als Arrays in anderen Programmiersprachen. Sie sind dynamisch und können wachsen oder schrumpfen, ohne eine feste Größe zu haben. Sie erlauben auch das Speichern von Elementen unterschiedlicher Typen, wie Zahlen, Strings und Objekte. Das macht sie flexibler im Vergleich zu Arrays in Sprachen wie Java, die eine feste Größe haben und nur Elemente eines einzigen Datentyps enthalten können. Zudem bieten JavaScript-Arrays zahlreiche eingebaute Methoden zur Manipulation von Daten, wie push, pop und shift, was sie vielseitiger und einfacher zu handhaben macht.
[[File:media/image10.png|624x361px]]


<span id="ereignisse"></span>
'''Ereignis: Tastatureingabe'''
=== Ereignisse ===


'''Ereignis''': Eine Aktion welche im System erkannt und darauf reagiert wird. Beispiele sind Mausklicks, Tastatureingaben oder das Laden einer Seite.
'''Beschreibung''': Zeigt eine Nachricht an, wenn die Eingabetaste gedrückt wird.


Mausklick:
<code class="mwt-code">// Ereignis-Handler für Tastatureingaben</code>


document.getElementById(&quot;zeigePublikation&quot;).addEventListener(&quot;click&quot;, function() {
<code class="mwt-code">document.addEventListener('keydown', (event) =</code>&gt;<code class="mwt-code"> {</code>


alert(&quot;Publikation: Deep Learning in AI&quot;);
<code class="mwt-code">if (event.key === 'Enter') {</code>


});
<code class="mwt-code">alert('Eingabetaste wurde gedrückt!');</code>


Mouseover (Maus über ein Element bewegen):
<code class="mwt-code">}</code>


document.getElementById(&quot;zeigePublikation&quot;).addEventListener(&quot;mouseover&quot;, function() {
<code class="mwt-code">});</code>


console.log(&quot;Maus ist über dem Publikationsbereich!&quot;);
[[File:media/image11.png|624x362px]]


});
'''Ereignis: Ändern eines Select-Menüs'''


Keydown (Tastendruck):
'''Beschreibung''': Zeigt die ausgewählte Option aus einem Dropdown-Menü an, wenn der Benutzer eine Auswahl trifft.


document.addEventListener(&quot;keydown&quot;, function(event) {
&lt;<code class="mwt-code">select id=</code>"<code class="mwt-code">rolle-select</code>"&gt;


console.log(&quot;Gedrückte Taste: &quot; + event.key);
&lt;<code class="mwt-code">option value=</code>"<code class="mwt-code">Autor</code>"&gt;<code class="mwt-code">Autor</code>&lt;<code class="mwt-code">/option</code>&gt;


});
&lt;<code class="mwt-code">option value=</code>"<code class="mwt-code">Gutachter</code>"&gt;<code class="mwt-code">Gutachter</code>&lt;<code class="mwt-code">/option</code>&gt;


Seitenladen (DOMContentLoaded):
&lt;<code class="mwt-code">option value=</code>"<code class="mwt-code">Leser</code>"&gt;<code class="mwt-code">Leser</code>&lt;<code class="mwt-code">/option</code>&gt;


document.addEventListener(&quot;DOMContentLoaded&quot;, function() {
&lt;<code class="mwt-code">/select</code>&gt;


console.log(&quot;Die Seite ist vollständig geladen!&quot;);
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">ausgewaehlte-rolle</code>"&gt;&lt;<code class="mwt-code">/div</code>&gt;


});
<code class="mwt-code">// Zugriff auf DOM-Elemente</code>


Formular absenden:
<code class="mwt-code">let rolleSelectElement = document.getElementById('rolle-select');</code>


document.getElementById(&quot;publikationsFormular&quot;).addEventListener(&quot;submit&quot;, function(event) {
<code class="mwt-code">let ausgewaehlteRolleElement = document.getElementById('ausgewaehlte-rolle');</code>


event.preventDefault(); // Verhindert das Standardverhalten
<code class="mwt-code">// Ereignis-Handler für Änderungen des Select-Menüs</code>


alert(&quot;Formular zur Publikation wurde abgesendet!&quot;);
<code class="mwt-code">rolleSelectElement.addEventListener('change', () =</code>&gt;<code class="mwt-code"> {</code>


});
<code class="mwt-code">let ausgewaehlteRolle = rolleSelectElement.value;</code>


<span id="fehlerbehandlung"></span>
<code class="mwt-code">ausgewaehlteRolleElement.textContent = `Ausgewählte Rolle: ${ausgewaehlteRolle}`;</code>
=== Fehlerbehandlung ===


'''Fehlerbehandlung''': Verwendung von try, catch, finally und throw, um Fehler zu erkennen und zu verarbeiten.
<code class="mwt-code">});</code>


try {
[[File:media/image12.png|624x361px]]


let neuerGutachter = neuerBenutzer('alice_wonderland', 'alice@example.com', 'hashed_password3', 'Gutachter');
<span id="frameworks"></span>


if (!neuerGutachter.email.includes('@')) {
= Frameworks =


throw new Error('Ungültige E-Mail-Adresse');
JavaScript-Frameworks erleichtern die Webentwicklung, indem sie strukturierte Ansätze, wiederverwendbare Komponenten und integrierte Funktionen bieten. Die meistverwendeten Frameworks sind React (Meta, 2024), Angular (Google, 2024) und Vue.js (You, 2024). React, von Facebook entwickelt, konzentriert sich auf die Erstellung von Benutzeroberflächen mit einem komponentenbasierten Modell und einem Virtual DOM für effiziente Updates. Angular, gepflegt von Google, bietet eine umfassende Lösung für große Webanwendungen, inklusive Dependency Injection und Routing, und verwendet TypeScript für statische Typisierung. Vue.js ist ein leichtgewichtiges Framework, das einfach zu integrieren und zu lernen ist, und bietet eine flexible API, die Elemente von React und Angular kombiniert. Die Wahl eines Frameworks hängt von den spezifischen Projektanforderungen ab. Diese Frameworks sparen Zeit, verbessern die Code-Qualität, optimieren die Leistung und bieten umfassende Dokumentation sowie Community-Support, was zu schnellerer, konsistenterer und wartbarer Entwicklung führt.


}
<span id="react"></span>
== React ==


} catch (error) {
React ist eine JavaScript-Bibliothek, die es ermöglicht, komplexe Benutzeroberflächen in wiederverwendbare, isolierte Komponenten zu zerlegen. Diese Komponenten verwalten ihren eigenen Zustand und nutzen einen virtuellen DOM, um effizient Änderungen an der Benutzeroberfläche vorzunehmen. Dies führt zu einer reaktiven und schnellen Anwendung.


console.log(error.message);
<span id="komponenten"></span>
=== Komponenten ===


}
In React ist eine Komponente ein selbstständiges, wiederverwendbares Stück der Benutzeroberfläche. Sie kann in andere Komponenten eingebettet werden und hat ihren eigenen Zustand und ihre eigene Logik.


<span id="module"></span>
'''Beispiel:''' Für unsere Anwendung könnten wir eine Publikation-Komponente erstellen, die die Details einer wissenschaftlichen Publikation anzeigt.
=== Module ===


'''Module''': Erlauben es, Code in separate Dateien zu unterteilen. Jedes Modul kann Werte oder Funktionen exportieren und in anderen Dateien importieren.
<code class="mwt-code" >function Publikation({ titel, abstract, inhalt }) {</code>


// benutzer.js
<code class="mwt-code" >return (</code>


export function neuerBenutzer(benutzername, email, passwort, rolle) {
&lt;<code class="mwt-code" >div</code>&gt;


return {
&lt;<code class="mwt-code" >h2</code>&gt;<code class="mwt-code" >{titel}</code>&lt;<code class="mwt-code" >/h2</code>&gt;


benutzername: benutzername,
&lt;<code class="mwt-code" >p</code>&gt;<code class="mwt-code" >{abstract}</code>&lt;<code class="mwt-code" >/p</code>&gt;


email: email,
&lt;<code class="mwt-code" >div</code>&gt;<code class="mwt-code" >{inhalt}</code>&lt;<code class="mwt-code" >/div</code>&gt;


passwort: passwort,
&lt;<code class="mwt-code" >/div</code>&gt;


rolle: rolle
<code class="mwt-code" >);</code>


};
<code class="mwt-code" >}</code>


}
In diesem Beispiel ist Publikation eine Komponente, die titel, abstract und inhalt als Props erhält und diese Daten in der Benutzeroberfläche darstellt.


// main.js
<span id="jsx"></span>
=== JSX ===


import { neuerBenutzer } from './benutzer.js';
JSX ist eine Syntaxerweiterung für JavaScript, die es ermöglicht, HTML-ähnlichen Code direkt in JavaScript zu schreiben. Dieser Code wird von React in regulären JavaScript-Code übersetzt.


let neuerLeser = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password4', 'Leser');
'''Beispiel:''' Das folgende JSX beschreibt die Struktur eines Kommentarformulars.


console.log(neuerLeser);
<code class="mwt-code" >function KommentarFormular() {</code>


<span id="dom-dom-dom"></span>
<code class="mwt-code" >return (</code>
= DOM, DOM, DOM =


Der '''Document Object Model (DOM)''' ist eine Programmierschnittstelle für HTML- und XML-Dokumente. Es repräsentiert die Struktur eines Dokuments als eine Baumstruktur, wobei jede HTML- oder XML-Komponente (wie Tags, Attribute und Text) als Knoten dargestellt wird. Mit dem DOM können Sie die Struktur, den Inhalt und das Styling eines Dokuments dynamisch ändern.
&lt;<code class="mwt-code" >form</code>&gt;


Kommen wir zurück zu unserem Fallbeispiel. Auf unserer Webseite möchten wir Informationen zu Publikationen anzeigen und es den Benutzern ermöglichen, Kommentare zu hinterlassen.
&lt;<code class="mwt-code" >textarea placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;<code class="mwt-code" > /</code>&gt;


Ein einfaches HTML-Dokument für unser System könnte wie folgt aussehen:
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


&lt;!DOCTYPE html&gt;
&lt;<code class="mwt-code" >/form</code>&gt;


&lt;html lang=&quot;de&quot;&gt;
<code class="mwt-code" >);</code>


&lt;head&gt;
<code class="mwt-code" >}</code>


&lt;meta charset=&quot;UTF-8&quot;&gt;
Hier sehen wir, wie HTML-ähnlicher Code in JavaScript eingebettet wird, um die Benutzeroberfläche zu definieren.


&lt;title&gt;Publikationen&lt;/title&gt;
<span id="props"></span>
=== Props ===


&lt;/head&gt;
Props (Eigenschaften) sind Parameter, die an Komponenten übergeben werden, um Daten weiterzugeben. Sie sind unveränderlich innerhalb der Komponente.


&lt;body&gt;
'''Beispiel:''' In der App-Komponente übergeben wir Daten an die Publikation-Komponente.


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
<code class="mwt-code" >function App() {</code>


&lt;div id=&quot;publikation-container&quot;&gt;
<code class="mwt-code" >return (</code>


&lt;h2 id=&quot;publikation-titel&quot;&gt;Gibt es die Matrix wirklich?&lt;/h2&gt;
&lt;<code class="mwt-code" >Publikation</code>


&lt;p id=&quot;publikation-abstract&quot;&gt;Eine umfassende Analyse der Frage, ob wir in einer simulierten Realität leben.&lt;/p&gt;
<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >Gibt es die Matrix wirklich?</code>&quot;


&lt;div id=&quot;kommentare&quot;&gt;
<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >Eine Untersuchung der Realität und ihrer Möglichkeiten.</code>&quot;


&lt;h3&gt;Kommentare&lt;/h3&gt;
<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.</code>&quot;


&lt;!-- Kommentare werden hier hinzugefügt --&gt;
<code class="mwt-code" >/</code>&gt;


&lt;/div&gt;
<code class="mwt-code" >);</code>


&lt;textarea id=&quot;neuer-kommentar&quot; placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;&gt;&lt;/textarea&gt;
<code class="mwt-code" >}</code>


&lt;button id=&quot;kommentar-hinzufuegen&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
Hier erhält Publikation die Daten als Props und zeigt diese in der Benutzeroberfläche an.


&lt;/div&gt;
<span id="state"></span>
=== State ===


&lt;script src=&quot;app.js&quot;&gt;&lt;/script&gt;
Der State ist der interne Zustand einer Komponente, der sich ändern kann und die Darstellung der Komponente beeinflusst. Er ist veränderbar und ermöglicht es, die Benutzeroberfläche dynamisch zu aktualisieren.


&lt;/body&gt;
'''Beispiel:''' In der KommentarFormular-Komponente verwalten wir den Text des Kommentars im State.


&lt;/html&gt;
<code class="mwt-code" >import React, { useState } from 'react';</code>


[[File:media/image4.png|624x362px]]
<code class="mwt-code" >function KommentarFormular() {</code>


In diesem Beispiel haben wir HTML-Elemente wie h1, h2, p, div, textarea und button, die verschiedene Teile unserer Publikationsseite darstellen. Das DOM repräsentiert diese Elemente als Knoten in einem Baum.
<code class="mwt-code" >const [kommentar, setKommentar] = useState('');</code>


In unserem JavaScript-Code können wir auf diese DOM-Elemente zugreifen und sie manipulieren. Erstelle in demselben Ordner eine neue Datei app.js. In dieser Datei schreiben wir den JavaScript Code. Auf diesen wird in dem obigen Beispiel mit &lt;script src=“app.js“&gt; zugegriffen. Manipulieren wir nun die HTML Datei mit JavaScript code. Hier sind einige Beispiele:
<code class="mwt-code" >const handleChange = (event) =</code>&gt;<code class="mwt-code" > {</code>


// Zugriff auf DOM-Elemente
<code class="mwt-code" >setKommentar(event.target.value);</code>


let titelElement = document.getElementById('publikation-titel');
<code class="mwt-code" >};</code>


let abstractElement = document.getElementById('publikation-abstract');
<code class="mwt-code" >const handleSubmit = (event) =</code>&gt;<code class="mwt-code" > {</code>


let kommentareElement = document.getElementById('kommentare');
<code class="mwt-code" >event.preventDefault();</code>


let textareaElement = document.getElementById('neuer-kommentar');
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + kommentar);</code>


let buttonElement = document.getElementById('kommentar-hinzufuegen');
<code class="mwt-code" >setKommentar('');</code>


// Hinzufügen eines Kommentars
<code class="mwt-code" >};</code>


buttonElement.addEventListener('click', () =&gt; {
<code class="mwt-code" >return (</code>


let neuerKommentar = textareaElement.value;
&lt;<code class="mwt-code" >form onSubmit={handleSubmit}</code>&gt;


if (neuerKommentar) {
&lt;<code class="mwt-code" >textarea</code>


let kommentarElement = document.createElement('p');
<code class="mwt-code" >value={kommentar}</code>


kommentarElement.textContent = neuerKommentar;
<code class="mwt-code" >onChange={handleChange}</code>


kommentareElement.appendChild(kommentarElement);
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


textareaElement.value = ''; // Textarea leeren
<code class="mwt-code" >/</code>&gt;


} else {
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


alert('Bitte geben Sie einen Kommentar ein.');
&lt;<code class="mwt-code" >/form</code>&gt;


}
<code class="mwt-code" >);</code>


});
<code class="mwt-code" >}</code>


Öffne die HTML Datei erneut in deinem Browser und siehe was sich verändert hat.
Hier verwenden wir den State, um den aktuellen Kommentar zu speichern und die Benutzeroberfläche bei Änderungen zu aktualisieren.


[[File:media/image5.png|624x364px]]
<span id="lifecycle-methoden"></span>
=== Lifecycle-Methoden ===


[[File:media/image6.png|624x364px]]
Lifecycle-Methoden sind spezielle Methoden, die zu verschiedenen Zeitpunkten im Lebenszyklus einer Komponente aufgerufen werden. Bei funktionalen Komponenten werden Hooks verwendet, um ähnliche Funktionalität zu erreichen.


Im obigen JavaScript-Beispiel verwenden wir das DOM, um:
'''Beispiel:''' In einer PublikationenListe-Komponente laden wir beim ersten Rendern Daten von einem Server:


* '''Elemente zu finden''': Wir greifen auf Elemente wie den Titel und das Abstract der Publikation zu.
<code class="mwt-code" >import React, { useEffect, useState } from 'react';</code>
* '''Ereignisse zu behandeln''': Wir fügen einen Event-Listener für den Button hinzu, um einen Kommentar hinzuzufügen, wenn der Button geklickt wird.
* '''Elemente zu erstellen und zu modifizieren''': Wir erstellen neue p-Elemente für Kommentare und fügen sie dem DOM hinzu. Außerdem ändern wir den Inhalt von textarea und leeren ihn nach dem Hinzufügen eines Kommentars.
*


Die Baumstruktur des DOM für unser Beispiel sieht folgendermaßen aus:
<code class="mwt-code" >function PublikationenListe() {</code>


&lt;html&gt;
<code class="mwt-code" >const [publikationen, setPublikationen] = useState([]);</code>


&lt;head&gt;
<code class="mwt-code" >useEffect(() =</code>&gt;<code class="mwt-code" > {</code>


&lt;meta&gt;
<code class="mwt-code" >fetch('/api/publikationen')</code>


&lt;title&gt;
<code class="mwt-code" >.then(response =</code>&gt;<code class="mwt-code" > response.json())</code>


&lt;body&gt;
<code class="mwt-code" >.then(data =</code>&gt;<code class="mwt-code" > setPublikationen(data));</code>


&lt;h1&gt;
<code class="mwt-code" >}, []); // Leeres Array bedeutet, dass es nur einmal ausgeführt wird</code>


&lt;div id=&quot;publikation-container&quot;&gt;
<code class="mwt-code" >return (</code>


&lt;h2 id=&quot;publikation-titel&quot;&gt;
&lt;<code class="mwt-code" >div</code>&gt;


&lt;p id=&quot;publikation-abstract&quot;&gt;
<code class="mwt-code" >{publikationen.map(publikation =</code>&gt;<code class="mwt-code" > (</code>


&lt;div id=&quot;kommentare&quot;&gt;
&lt;<code class="mwt-code" >Publikation</code>


&lt;h3&gt;
<code class="mwt-code" >key={publikation.id}</code>


(Kommentare werden hier hinzugefügt)
<code class="mwt-code" >titel={publikation.titel}</code>


&lt;textarea id=&quot;neuer-kommentar&quot;&gt;
<code class="mwt-code" >abstract={publikation.abstract}</code>


&lt;button id=&quot;kommentar-hinzufuegen&quot;&gt;
<code class="mwt-code" >inhalt={publikation.inhalt}</code>


Sehen wir uns nun weitere Beispiele von Ereignissen an.
<code class="mwt-code" >/</code>&gt;


'''Ereignis: Eingabe in Textarea'''
<code class="mwt-code" >))}</code>


'''Beschreibung''': Zeigt eine Live-Vorschau des eingegebenen Kommentars an, während der Benutzer tippt.
&lt;<code class="mwt-code" >/div</code>&gt;


// Zugriff auf DOM-Elemente
<code class="mwt-code" >);</code>


let textareaElement = document.getElementById('neuer-kommentar');
<code class="mwt-code" >}</code>


let liveVorschauElement = document.createElement('div');
Hier verwenden wir useEffect, um Daten beim ersten Rendern der Komponente abzurufen.


liveVorschauElement.id = 'live-vorschau';
<span id="virtual-dom"></span>
=== Virtual DOM ===


document.body.appendChild(liveVorschauElement);
Der Virtual DOM ist eine in-memory-Repräsentation des echten DOMs. React verwendet den Virtual DOM, um Änderungen effizienter zu verarbeiten, indem es nur die Teile des echten DOMs aktualisiert, die tatsächlich verändert wurden. Diese Optimierung wird automatisch von React gehandhabt, daher müssen wir keinen speziellen Code dafür schreiben.


// Ereignis-Handler für die Eingabe in die Textarea
<span id="event-handling"></span>
=== Event-Handling ===


textareaElement.addEventListener('input', () =&gt; {
React ermöglicht die Behandlung von Benutzerereignissen wie Klicks und Eingaben direkt innerhalb der JSX-Syntax.


let eingabeText = textareaElement.value;
'''Beispiel:''' In einer KommentarFormular-Komponente verarbeiten wir das Absenden des Formulars:


liveVorschauElement.textContent = `Vorschau: ${eingabeText}`;
<code class="mwt-code" >function KommentarFormular() {</code>


});
<code class="mwt-code" >const [kommentar, setKommentar] = useState('');</code>


[[File:media/image7.png|624x363px]]
<code class="mwt-code" >const handleSubmit = (event) =</code>&gt;<code class="mwt-code" > {</code>


'''Ereignis: Mausbewegung'''
<code class="mwt-code" >event.preventDefault();</code>


'''Beschreibung''': Ändert die Hintergrundfarbe eines Elements, wenn die Maus darüber bewegt wird.
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + kommentar);</code>


// Zugriff auf DOM-Element
<code class="mwt-code" >setKommentar('');</code>


let titelElement = document.getElementById('publikation-titel');
<code class="mwt-code" >};</code>


// Ereignis-Handler für Mausbewegung
<code class="mwt-code" >return (</code>


titelElement.addEventListener('mouseover', () =&gt; {
&lt;<code class="mwt-code" >form onSubmit={handleSubmit}</code>&gt;


titelElement.style.backgroundColor = '#f0f0f0'; // Hintergrundfarbe ändern
&lt;<code class="mwt-code" >textarea</code>


});
<code class="mwt-code" >value={kommentar}</code>


// Ereignis-Handler für Mausverlassen
<code class="mwt-code" >onChange={(e) =</code>&gt;<code class="mwt-code" > setKommentar(e.target.value)}</code>


titelElement.addEventListener('mouseout', () =&gt; {
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


titelElement.style.backgroundColor = ''; // Hintergrundfarbe zurücksetzen
<code class="mwt-code" >/</code>&gt;


});
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


[[File:media/image8.png|624x360px]]
&lt;<code class="mwt-code" >/form</code>&gt;


'''Ereignis: Formular-Submit'''
<code class="mwt-code" >);</code>


'''Beschreibung''': Verhindert das Standard-Submit-Verhalten eines Formulars und zeigt stattdessen eine Bestätigungsmeldung an.
<code class="mwt-code" >}</code>


index.html
Hier wird der onSubmit-Event-Handler verwendet, um den Kommentar beim Absenden des Formulars zu verarbeiten.


&lt;form id=&quot;kommentar-form&quot;&gt;
<span id="hooks"></span>
=== Hooks ===


&lt;textarea id=&quot;neuer-kommentar&quot; placeholder=&quot;Fuegen Sie einen Kommentar hinzu...&quot;&gt;
Hooks sind Funktionen, die es ermöglichen, in funktionalen Komponenten auf den State und andere React-Funktionen zuzugreifen.


&lt;/textarea&gt;
'''Beispiel:''' Mit useState und useEffect können wir Zustand und Nebenwirkungen in funktionalen Komponenten verwalten:


&lt;button type=&quot;submit&quot; id=&quot;kommentar-hinzufuegen&quot;&gt;Kommentar hinzufuegen
<code class="mwt-code" >import React, { useState, useEffect } from 'react';</code>


&lt;/button&gt;
<code class="mwt-code" >function KommentarFormular() {</code>


&lt;/form&gt;
<code class="mwt-code" >const [kommentar, setKommentar] = useState('');</code>


&lt;script src=&quot;app.js&quot;&gt;&lt;/script&gt;
<code class="mwt-code" >useEffect(() =</code>&gt;<code class="mwt-code" > {</code>


app.js
<code class="mwt-code" >console.log('KommentarFormular gerendert');</code>


// Zugriff auf DOM-Elemente
<code class="mwt-code" >}, []);</code>


let textareaElement = document.getElementById('neuer-kommentar');
<code class="mwt-code" >return (</code>


let formElement = document.getElementById('kommentar-form');
&lt;<code class="mwt-code" >form</code>&gt;


// Ereignis-Handler für Formular-Submit
&lt;<code class="mwt-code" >textarea</code>


formElement.addEventListener('submit', (event) =&gt; {
<code class="mwt-code" >value={kommentar}</code>


event.preventDefault(); // Verhindert das Standard-Submit-Verhalten
<code class="mwt-code" >onChange={(e) =</code>&gt;<code class="mwt-code" > setKommentar(e.target.value)}</code>


let neuerKommentar = textareaElement.value;
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


if (neuerKommentar) {
<code class="mwt-code" >/</code>&gt;


let kommentarElement = document.createElement('p');
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >button</code>&quot;<code class="mwt-code" > onClick={() =</code>&gt;<code class="mwt-code" > alert('Kommentar hinzugefügt: ' + kommentar)}</code>&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


kommentarElement.textContent = neuerKommentar;
&lt;<code class="mwt-code" >/form</code>&gt;


textareaElement.value = ''; // Textarea leeren
<code class="mwt-code" >);</code>


alert('Kommentar erfolgreich hinzugefuegt!');
<code class="mwt-code" >}</code>


} else {
Hier verwenden wir useState, um den Kommentar zu speichern, und useEffect, um einen Effekt nach dem ersten Rendern auszuführen.


alert('Bitte geben Sie einen Kommentar ein.');
<span id="erste-react-applikation-in-vscode"></span>
=== Erste React Applikation in VSCode ===


}
Da wir nun die wichtigsten Konzepte, die React verwendet, kennengelernt haben, können wir nun unsere erste React App in VSCode ertellen.


});
'''Installiere Node.js und npm'''


[[File:media/image9.png|624x361px]]
Besuche die [https://nodejs.org/ Node.js-Website] und lade die neueste LTS-Version herunter. Dies installiert auch npm, das für das Verwalten von Paketen verwendet wird.


[[File:media/image10.png|624x361px]]
'''Installiere create-react-app'''


'''Ereignis: Tastatureingabe'''
Öffne dein Terminal oder die Kommandozeile und installiere das create-react-app-Tool global:


'''Beschreibung''': Zeigt eine Nachricht an, wenn die Eingabetaste gedrückt wird.
npm install -g create-react-app


// Ereignis-Handler für Tastatureingaben
'''Erstelle ein neues React-Projekt'''


document.addEventListener('keydown', (event) =&gt; {
Gehen wir in das Verzeichnis, in dem das Projekt erstellt werden soll, und führen wir diesen Befehl aus:


if (event.key === 'Enter') {
npx create-react-app from-peer-review-to-crowd-review


alert('Eingabetaste wurde gedrückt!');
Dieser Befehl erstellt ein neues Verzeichnis namens fromPeerReviewToCrowdReview mit einer grundlegenden React-Anwendung.


}
'''Öffne das Projekt in Visual Studio Code'''


});
Starte Visual Studio Code und öffne das Projektverzeichnis. Alternativ kannst man im Terminal folgenden Befehl verwenden:


[[File:media/image11.png|624x362px]]
code from-peer-review-to-crowd-review


'''Ereignis: Ändern eines Select-Menüs'''
'''Starte den Entwicklungsserver'''


'''Beschreibung''': Zeigt die ausgewählte Option aus einem Dropdown-Menü an, wenn der Benutzer eine Auswahl trifft.
Öffne das integrierte Terminal in VSCode (Terminal &gt; Neues Terminal) und starte die Entwicklungsumgebung:


&lt;select id=&quot;rolle-select&quot;&gt;
npm start


&lt;option value=&quot;Autor&quot;&gt;Autor&lt;/option&gt;
Dies startet den Entwicklungsserver und öffnet deine Anwendung in einem Webbrowser. Der Server überwacht Änderungen an deinem Code und aktualisiert die Anwendung automatisch.


&lt;option value=&quot;Gutachter&quot;&gt;Gutachter&lt;/option&gt;
'''Bearbeite die Anwendung'''


&lt;option value=&quot;Leser&quot;&gt;Leser&lt;/option&gt;
Gehe zur Datei src/App.js. Ändere den Code, um die Benutzeroberfläche für unsere Anwendung darzustellen:


&lt;/select&gt;
i<code class="mwt-code" >mport React from 'react';</code>


&lt;div id=&quot;ausgewaehlte-rolle&quot;&gt;&lt;/div&gt;
<code class="mwt-code" >import Publikation from './Publikation'; // Importiere die neue Komponente</code>


// Zugriff auf DOM-Elemente
<code class="mwt-code" >function App() {</code>


let rolleSelectElement = document.getElementById('rolle-select');
<code class="mwt-code" >return (</code>


let ausgewaehlteRolleElement = document.getElementById('ausgewaehlte-rolle');
&lt;<code class="mwt-code" >div className=</code>&quot;<code class="mwt-code" >App</code>&quot;&gt;


// Ereignis-Handler für Änderungen des Select-Menüs
&lt;<code class="mwt-code" >header className=</code>&quot;<code class="mwt-code" >App-header</code>&quot;&gt;


rolleSelectElement.addEventListener('change', () =&gt; {
&lt;<code class="mwt-code" >h1</code>&gt;<code class="mwt-code" >Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code" >/h1</code>&gt;


let ausgewaehlteRolle = rolleSelectElement.value;
&lt;<code class="mwt-code" >Publikation</code>


ausgewaehlteRolleElement.textContent = `Ausgewählte Rolle: ${ausgewaehlteRolle}`;
<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >Gibt es die Matrix wirklich?</code>&quot;


});
<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >Eine Untersuchung der Realität und ihrer Möglichkeiten.</code>&quot;


[[File:media/image12.png|624x361px]]
<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.</code>&quot;


<span id="frameworks"></span>
<code class="mwt-code" >/</code>&gt;
= Frameworks =


JavaScript-Frameworks erleichtern die Webentwicklung, indem sie strukturierte Ansätze, wiederverwendbare Komponenten und integrierte Funktionen bieten. Die meistverwendeten Frameworks sind React (Meta, 2024), Angular (Google, 2024) und Vue.js (You, 2024). React, von Facebook entwickelt, konzentriert sich auf die Erstellung von Benutzeroberflächen mit einem komponentenbasierten Modell und einem Virtual DOM für effiziente Updates. Angular, gepflegt von Google, bietet eine umfassende Lösung für große Webanwendungen, inklusive Dependency Injection und Routing, und verwendet TypeScript für statische Typisierung. Vue.js ist ein leichtgewichtiges Framework, das einfach zu integrieren und zu lernen ist, und bietet eine flexible API, die Elemente von React und Angular kombiniert. Die Wahl eines Frameworks hängt von den spezifischen Projektanforderungen ab. Diese Frameworks sparen Zeit, verbessern die Code-Qualität, optimieren die Leistung und bieten umfassende Dokumentation sowie Community-Support, was zu schnellerer, konsistenterer und wartbarer Entwicklung führt.
&lt;<code class="mwt-code" >/header</code>&gt;


<span id="react"></span>
&lt;<code class="mwt-code" >/div</code>&gt;
== React ==


React ist eine JavaScript-Bibliothek, die es ermöglicht, komplexe Benutzeroberflächen in wiederverwendbare, isolierte Komponenten zu zerlegen. Diese Komponenten verwalten ihren eigenen Zustand und nutzen einen virtuellen DOM, um effizient Änderungen an der Benutzeroberfläche vorzunehmen. Dies führt zu einer reaktiven und schnellen Anwendung.
<code class="mwt-code" >);</code>


<span id="komponenten"></span>
<code class="mwt-code" >}</code>
=== Komponenten ===


In React ist eine Komponente ein selbstständiges, wiederverwendbares Stück der Benutzeroberfläche. Sie kann in andere Komponenten eingebettet werden und hat ihren eigenen Zustand und ihre eigene Logik.
export default App;


'''Beispiel:''' Für unsere Anwendung könnten wir eine Publikation-Komponente erstellen, die die Details einer wissenschaftlichen Publikation anzeigt.
'''Füge eine neue Komponente hinzu'''


function Publikation({ titel, abstract, inhalt }) {
Erstelle eine neue Datei src/Publikation.js für die Publikation-Komponente:


return (
<code class="mwt-code" >import React from 'react';</code>


&lt;div&gt;
<code class="mwt-code" >function Publikation({ titel, abstract, inhalt }) {</code>


&lt;h2&gt;{titel}&lt;/h2&gt;
<code class="mwt-code" >return (</code>


&lt;p&gt;{abstract}&lt;/p&gt;
&lt;<code class="mwt-code" >div</code>&gt;


&lt;div&gt;{inhalt}&lt;/div&gt;
&lt;<code class="mwt-code" >h2</code>&gt;<code class="mwt-code" >{titel}</code>&lt;<code class="mwt-code" >/h2</code>&gt;


&lt;/div&gt;
&lt;<code class="mwt-code" >p</code>&gt;<code class="mwt-code" >{abstract}</code>&lt;<code class="mwt-code" >/p</code>&gt;


);
&lt;<code class="mwt-code" >div</code>&gt;<code class="mwt-code" >{inhalt}</code>&lt;<code class="mwt-code" >/div</code>&gt;


}
&lt;<code class="mwt-code" >/div</code>&gt;


In diesem Beispiel ist Publikation eine Komponente, die titel, abstract und inhalt als Props erhält und diese Daten in der Benutzeroberfläche darstellt.
<code class="mwt-code" >);</code>


<span id="jsx"></span>
<code class="mwt-code" >}</code>
=== JSX ===


JSX ist eine Syntaxerweiterung für JavaScript, die es ermöglicht, HTML-ähnlichen Code direkt in JavaScript zu schreiben. Dieser Code wird von React in regulären JavaScript-Code übersetzt.
export default Publikation;


'''Beispiel:''' Das folgende JSX beschreibt die Struktur eines Kommentarformulars.
'''Füge weitere Komponenten hinzu'''


function KommentarFormular() {
Wir können nun weitere Komponenten erstellen, die beispielsweise das Kommentarformular und andere Teile der Anwendung zu integrieren. Zum Beispiel, erstelle src/KommentarFormular.js:


return (
<code class="mwt-code" >import React, { useState } from 'react';</code>


&lt;form&gt;
<code class="mwt-code" >function KommentarFormular() {</code>


&lt;textarea placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot; /&gt;
<code class="mwt-code" >const [kommentar, setKommentar] = useState('');</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >const handleChange = (event) =</code>&gt;<code class="mwt-code" > {</code>


&lt;/form&gt;
<code class="mwt-code" >setKommentar(event.target.value);</code>


);
<code class="mwt-code" >};</code>


}
<code class="mwt-code" >const handleSubmit = (event) =</code>&gt;<code class="mwt-code" > {</code>


Hier sehen wir, wie HTML-ähnlicher Code in JavaScript eingebettet wird, um die Benutzeroberfläche zu definieren.
<code class="mwt-code" >event.preventDefault();</code>


<span id="props"></span>
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + kommentar);</code>
=== Props ===


Props (Eigenschaften) sind Parameter, die an Komponenten übergeben werden, um Daten weiterzugeben. Sie sind unveränderlich innerhalb der Komponente.
<code class="mwt-code" >setKommentar('');</code>


'''Beispiel:''' In der App-Komponente übergeben wir Daten an die Publikation-Komponente.
<code class="mwt-code" >};</code>


function App() {
<code class="mwt-code" >return (</code>


return (
&lt;<code class="mwt-code" >form onSubmit={handleSubmit}</code>&gt;


&lt;Publikation
&lt;<code class="mwt-code" >textarea</code>


titel=&quot;Gibt es die Matrix wirklich?&quot;
<code class="mwt-code" >value={kommentar}</code>


abstract=&quot;Eine Untersuchung der Realität und ihrer Möglichkeiten.&quot;
<code class="mwt-code" >onChange={handleChange}</code>


inhalt=&quot;Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.&quot;
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


/&gt;
<code class="mwt-code" >/</code>&gt;


);
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


}
&lt;<code class="mwt-code" >/form</code>&gt;


Hier erhält Publikation die Daten als Props und zeigt diese in der Benutzeroberfläche an.
<code class="mwt-code" >);</code>


<span id="state"></span>
<code class="mwt-code" >}</code>
=== State ===


Der State ist der interne Zustand einer Komponente, der sich ändern kann und die Darstellung der Komponente beeinflusst. Er ist veränderbar und ermöglicht es, die Benutzeroberfläche dynamisch zu aktualisieren.
export default KommentarFormular;


'''Beispiel:''' In der KommentarFormular-Komponente verwalten wir den Text des Kommentars im State.
Importiere und verwende diese Komponente in App.js.


import React, { useState } from 'react';
<span id="angular"></span>
== Angular ==


function KommentarFormular() {
Angular ist ein weit verbreitetes Framework für die Entwicklung von Webanwendungen, das von Google entwickelt wird. Es basiert auf TypeScript und bietet eine strukturierte Architektur für den Aufbau von Single-Page-Anwendungen. Angular nutzt Komponenten als grundlegende Bausteine für die Benutzeroberfläche und bietet eine Vielzahl von Funktionen wie Datenbindung, Dependency Injection und Routing, um die Entwicklung und Wartung von komplexen Anwendungen zu erleichtern. Es enthält auch ein leistungsstarkes CLI (Command Line Interface) zum Generieren von Code und zur Verwaltung von Projekten. Angular ist bekannt für seine umfassenden Features und seine robuste Architektur, die es für große und skalierbare Projekte geeignet macht.


const [kommentar, setKommentar] = useState('');
<span id="komponenten-1"></span>
=== Komponenten ===
 
In Angular sind Komponenten die Hauptbausteine der Benutzeroberfläche. Jede Komponente besteht aus einer HTML-Vorlage, einer CSS-Datei für das Styling und einer TypeScript-Datei für die Logik.


const handleChange = (event) =&gt; {
'''Beispiel:''' Erstellen wir eine PublikationComponent, um eine Publikation anzuzeigen.


setKommentar(event.target.value);
'''HTML-Datei (publikation.component.html):'''


};
&lt;<code class="mwt-code" >div</code>&gt;


const handleSubmit = (event) =&gt; {
&lt;<code class="mwt-code" >h2</code>&gt;{{ titel }}&lt;<code class="mwt-code" >/h2</code>&gt;


event.preventDefault();
&lt;<code class="mwt-code" >p</code>&gt;{{ abstract }}&lt;<code class="mwt-code" >/p</code>&gt;


alert('Kommentar hinzugefügt: ' + kommentar);
&lt;<code class="mwt-code" >div</code>&gt;{{ inhalt }}&lt;<code class="mwt-code" >/div</code>&gt;


setKommentar('');
&lt;<code class="mwt-code" >/div</code>&gt;


};
'''TypeScript-Datei (publikation.component.ts):'''


return (
<code class="mwt-code" >import { Component, Input } from '@angular/core';</code>


&lt;form onSubmit={handleSubmit}&gt;
<code class="mwt-code" >@Component({</code>


&lt;textarea
<code class="mwt-code" >selector: 'app-publikation',</code>


value={kommentar}
<code class="mwt-code" >templateUrl: './publikation.component.html',</code>


onChange={handleChange}
<code class="mwt-code" >styleUrls: ['./publikation.component.css']</code>


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
<code class="mwt-code" >})</code>


/&gt;
<code class="mwt-code" >export class PublikationComponent {</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >@Input() titel: string;</code>


&lt;/form&gt;
<code class="mwt-code" >@Input() abstract: string;</code>


);
<code class="mwt-code" >@Input() inhalt: string;</code>


}
<code class="mwt-code" >}</code>


Hier verwenden wir den State, um den aktuellen Kommentar zu speichern und die Benutzeroberfläche bei Änderungen zu aktualisieren.
<span id="module-1"></span>
=== Module ===


<span id="lifecycle-methoden"></span>
Angular-Anwendungen bestehen aus Modulen, die verschiedene Teile der Anwendung gruppieren. Ein Modul kann Komponenten, Dienste und andere Module enthalten.
=== Lifecycle-Methoden ===


Lifecycle-Methoden sind spezielle Methoden, die zu verschiedenen Zeitpunkten im Lebenszyklus einer Komponente aufgerufen werden. Bei funktionalen Komponenten werden Hooks verwendet, um ähnliche Funktionalität zu erreichen.
'''Beispiel:''' Definieren wir ein Modul für die Publikationsfunktionalität.


'''Beispiel:''' In einer PublikationenListe-Komponente laden wir beim ersten Rendern Daten von einem Server:
'''TypeScript-Datei (app.module.ts):'''


import React, { useEffect, useState } from 'react';
<code class="mwt-code" >import { NgModule } from '@angular/core';</code>


function PublikationenListe() {
<code class="mwt-code" >import { BrowserModule } from '@angular/platform-browser';</code>


const [publikationen, setPublikationen] = useState([]);
<code class="mwt-code" >import { AppComponent } from './app.component';</code>


useEffect(() =&gt; {
<code class="mwt-code" >import { PublikationComponent } from './publikation/publikation.component';</code>


fetch('/api/publikationen')
<code class="mwt-code" >@NgModule({</code>


.then(response =&gt; response.json())
<code class="mwt-code" >declarations: [</code>


.then(data =&gt; setPublikationen(data));
<code class="mwt-code" >AppComponent,</code>


}, []); // Leeres Array bedeutet, dass es nur einmal ausgeführt wird
<code class="mwt-code" >PublikationComponent</code>


return (
<code class="mwt-code" >],</code>


&lt;div&gt;
<code class="mwt-code" >imports: [</code>


{publikationen.map(publikation =&gt; (
<code class="mwt-code" >BrowserModule</code>


&lt;Publikation
<code class="mwt-code" >],</code>


key={publikation.id}
<code class="mwt-code" >providers: [],</code>


titel={publikation.titel}
<code class="mwt-code" >bootstrap: [AppComponent]</code>


abstract={publikation.abstract}
<code class="mwt-code" >})</code>


inhalt={publikation.inhalt}
<code class="mwt-code" >export class AppModule { }</code>


/&gt;
<span id="services"></span>
=== Services ===


))}
Services sind wiederverwendbare Klassen, die Logik und Datenmanagement bereitstellen. Sie werden oft verwendet, um Daten zwischen Komponenten zu teilen.


&lt;/div&gt;
'''Beispiel:'''&nbsp;Erstellen wir nun einen PublikationService, um Publikationen von einer API abzurufen.


);
'''TypeScript-Datei (publikation.service.ts):'''


}
<code class="mwt-code" >import { Injectable } from '@angular/core';</code>


Hier verwenden wir useEffect, um Daten beim ersten Rendern der Komponente abzurufen.
<code class="mwt-code" >import { HttpClient } from '@angular/common/http';</code>


<span id="virtual-dom"></span>
<code class="mwt-code" >import { Observable } from 'rxjs';</code>
=== Virtual DOM ===


Der Virtual DOM ist eine in-memory-Repräsentation des echten DOMs. React verwendet den Virtual DOM, um Änderungen effizienter zu verarbeiten, indem es nur die Teile des echten DOMs aktualisiert, die tatsächlich verändert wurden. Diese Optimierung wird automatisch von React gehandhabt, daher müssen wir keinen speziellen Code dafür schreiben.
<code class="mwt-code" >@Injectable({</code>


<span id="event-handling"></span>
<code class="mwt-code" >providedIn: 'root'</code>
=== Event-Handling ===


React ermöglicht die Behandlung von Benutzerereignissen wie Klicks und Eingaben direkt innerhalb der JSX-Syntax.
<code class="mwt-code" >})</code>


'''Beispiel:''' In einer KommentarFormular-Komponente verarbeiten wir das Absenden des Formulars:
<code class="mwt-code" >export class PublikationService {</code>


function KommentarFormular() {
<code class="mwt-code" >private apiUrl = 'https://api.example.com/publikationen';</code>


const [kommentar, setKommentar] = useState('');
<code class="mwt-code" >constructor(private http: HttpClient) { }</code>


const handleSubmit = (event) =&gt; {
<code class="mwt-code" >getPublikationen(): Observable</code>&lt;<code class="mwt-code" >any[]</code>&gt;<code class="mwt-code" > {</code>


event.preventDefault();
<code class="mwt-code" >return this.http.get</code>&lt;<code class="mwt-code" >any[]</code>&gt;<code class="mwt-code" >(this.apiUrl);</code>


alert('Kommentar hinzugefügt: ' + kommentar);
<code class="mwt-code" >}</code>


setKommentar('');
<code class="mwt-code" >}</code>


};
<span id="routing"></span>
=== Routing ===


return (
Angular-Routing ermöglicht das Navigieren zwischen verschiedenen Ansichten oder Komponenten innerhalb einer Anwendung.


&lt;form onSubmit={handleSubmit}&gt;
'''Beispiel:''' Konfigurieren wir Routen für die Publikationsansicht und ein Kommentarformular.


&lt;textarea
'''TypeScript-Datei (app-routing.module.ts):'''


value={kommentar}
<code class="mwt-code" >import { NgModule } from '@angular/core';</code>


onChange={(e) =&gt; setKommentar(e.target.value)}
<code class="mwt-code" >import { RouterModule, Routes } from '@angular/router';</code>


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
<code class="mwt-code" >import { PublikationComponent } from './publikation/publikation.component';</code>


/&gt;
<code class="mwt-code" >const routes: Routes = [</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >{ path: 'publikationen', component: PublikationComponent },</code>


&lt;/form&gt;
<code class="mwt-code" >{ path: '', redirectTo: '/publikationen', pathMatch: 'full' }</code>


);
<code class="mwt-code" >];</code>


}
<code class="mwt-code" >@NgModule({</code>


Hier wird der onSubmit-Event-Handler verwendet, um den Kommentar beim Absenden des Formulars zu verarbeiten.
<code class="mwt-code" >imports: [RouterModule.forRoot(routes)],</code>


<span id="hooks"></span>
<code class="mwt-code" >exports: [RouterModule]</code>
=== Hooks ===


Hooks sind Funktionen, die es ermöglichen, in funktionalen Komponenten auf den State und andere React-Funktionen zuzugreifen.
<code class="mwt-code" >})</code>


'''Beispiel:''' Mit useState und useEffect können wir Zustand und Nebenwirkungen in funktionalen Komponenten verwalten:
<code class="mwt-code" >export class AppRoutingModule { }</code>


import React, { useState, useEffect } from 'react';
<span id="datenbindung"></span>
=== Datenbindung ===


function KommentarFormular() {
Angular bietet verschiedene Arten der Datenbindung, einschließlich Einweg- und Zweiweg-Datenbindung, um Daten zwischen der Logik der Komponente und der Ansicht zu synchronisieren.


const [kommentar, setKommentar] = useState('');
'''Beispiel:''' Zeigen wir nun Daten aus dem PublikationService in der PublikationComponent an.


useEffect(() =&gt; {
'''TypeScript-Datei (publikation.component.ts):'''


console.log('KommentarFormular gerendert');
<code class="mwt-code" >import { Component, OnInit } from '@angular/core';</code>


}, []);
<code class="mwt-code" >import { PublikationService } from '../publikation.service';</code>


return (
<code class="mwt-code" >@Component({</code>


&lt;form&gt;
<code class="mwt-code" >selector: 'app-publikation',</code>


&lt;textarea
<code class="mwt-code" >templateUrl: './publikation.component.html',</code>


value={kommentar}
<code class="mwt-code" >styleUrls: ['./publikation.component.css']</code>


onChange={(e) =&gt; setKommentar(e.target.value)}
<code class="mwt-code" >})</code>


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
<code class="mwt-code" >export class PublikationComponent implements OnInit {</code>


/&gt;
<code class="mwt-code" >publikationen: any[] = [];</code>


&lt;button type=&quot;button&quot; onClick={() =&gt; alert('Kommentar hinzugefügt: ' + kommentar)}&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >constructor(private publikationService: PublikationService) { }</code>


&lt;/form&gt;
<code class="mwt-code" >ngOnInit(): void {</code>


);
<code class="mwt-code" >this.publikationService.getPublikationen().subscribe(data =</code>&gt;<code class="mwt-code" > {</code>


}
<code class="mwt-code" >this.publikationen = data;</code>


Hier verwenden wir useState, um den Kommentar zu speichern, und useEffect, um einen Effekt nach dem ersten Rendern auszuführen.
<code class="mwt-code" >});</code>


<span id="erste-react-applikation-in-vscode"></span>
<code class="mwt-code" >}</code>
=== Erste React Applikation in VSCode ===


Da wir nun die wichtigsten Konzepte, die React verwendet, kennengelernt haben, können wir nun unsere erste React App in VSCode ertellen.
<code class="mwt-code" >}</code>


'''Installiere Node.js und npm'''
<span id="forms"></span>
=== Forms ===


Besuche die [https://nodejs.org/ Node.js-Website] und lade die neueste LTS-Version herunter. Dies installiert auch npm, das für das Verwalten von Paketen verwendet wird.
Angular bietet sowohl Template-driven Forms als auch Reactive Forms für die Verarbeitung von Benutzereingaben.


'''Installiere create-react-app'''
'''Beispiel:''' Erstellen wir ein Formular zum Hinzufügen von Kommentaren.


Öffne dein Terminal oder die Kommandozeile und installiere das create-react-app-Tool global:
'''HTML-Datei (kommentar-formular.component.html):'''


npm install -g create-react-app
&lt;<code class="mwt-code" >form (ngSubmit)=</code>&quot;<code class="mwt-code" >onSubmit()</code>&quot;<code class="mwt-code" > #kommentarForm=</code>&quot;<code class="mwt-code" >ngForm</code>&quot;&gt;


'''Erstelle ein neues React-Projekt'''
&lt;<code class="mwt-code" >textarea</code>


Gehen wir in das Verzeichnis, in dem das Projekt erstellt werden soll, und führen wir diesen Befehl aus:
<code class="mwt-code" >name=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;


npx create-react-app from-peer-review-to-crowd-review
<code class="mwt-code" >[(ngModel)]=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;


Dieser Befehl erstellt ein neues Verzeichnis namens fromPeerReviewToCrowdReview mit einer grundlegenden React-Anwendung.
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


'''Öffne das Projekt in Visual Studio Code'''
<code class="mwt-code" >required</code>&gt;


Starte Visual Studio Code und öffne das Projektverzeichnis. Alternativ kannst man im Terminal folgenden Befehl verwenden:
&lt;<code class="mwt-code" >/textarea</code>&gt;


code from-peer-review-to-crowd-review
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


'''Starte den Entwicklungsserver'''
&lt;<code class="mwt-code" >/form</code>&gt;


Öffne das integrierte Terminal in VSCode (Terminal &gt; Neues Terminal) und starte die Entwicklungsumgebung:
'''TypeScript-Datei (kommentar-formular.component.ts):'''


npm start
<code class="mwt-code" >import { Component } from '@angular/core';</code>


Dies startet den Entwicklungsserver und öffnet deine Anwendung in einem Webbrowser. Der Server überwacht Änderungen an deinem Code und aktualisiert die Anwendung automatisch.
<code class="mwt-code" >@Component({</code>


'''Bearbeite die Anwendung'''
<code class="mwt-code" >selector: 'app-kommentar-formular',</code>


Gehe zur Datei src/App.js. Ändere den Code, um die Benutzeroberfläche für unsere Anwendung darzustellen:
<code class="mwt-code" >templateUrl: './kommentar-formular.component.html',</code>


import React from 'react';
<code class="mwt-code" >styleUrls: ['./kommentar-formular.component.css']</code>


import Publikation from './Publikation'; // Importiere die neue Komponente
<code class="mwt-code" >})</code>


function App() {
<code class="mwt-code" >export class KommentarFormularComponent {</code>


return (
<code class="mwt-code" >kommentar: string = '';</code>


&lt;div className=&quot;App&quot;&gt;
<code class="mwt-code" >onSubmit(): void {</code>


&lt;header className=&quot;App-header&quot;&gt;
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + this.kommentar);</code>


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
<code class="mwt-code" >this.kommentar = '';</code>


&lt;Publikation
<code class="mwt-code" >}</code>


titel=&quot;Gibt es die Matrix wirklich?&quot;
<code class="mwt-code" >}</code>


abstract=&quot;Eine Untersuchung der Realität und ihrer Möglichkeiten.&quot;
<span id="dependency-injection"></span>
=== Dependency Injection ===


inhalt=&quot;Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.&quot;
Angular verwendet Dependency Injection (DI), um Abhängigkeiten wie Services in Komponenten und andere Services einzufügen.


/&gt;
'''Beispiel:''' Der PublikationService wird in PublikationComponent durch DI eingefügt.


&lt;/header&gt;
'''TypeScript-Datei (publikation.component.ts):'''


&lt;/div&gt;
<code class="mwt-code" >import { Component, OnInit } from '@angular/core';</code>


);
<code class="mwt-code" >import { PublikationService } from '../publikation.service';</code>


}
<code class="mwt-code" >@Component({</code>


export default App;
<code class="mwt-code" >selector: 'app-publikation',</code>


'''Füge eine neue Komponente hinzu'''
<code class="mwt-code" >templateUrl: './publikation.component.html',</code>


Erstelle eine neue Datei src/Publikation.js für die Publikation-Komponente:
<code class="mwt-code" >styleUrls: ['./publikation.component.css']</code>


import React from 'react';
<code class="mwt-code" >})</code>


function Publikation({ titel, abstract, inhalt }) {
<code class="mwt-code" >export class PublikationComponent implements OnInit {</code>


return (
<code class="mwt-code" >publikationen: any[] = [];</code>


&lt;div&gt;
<code class="mwt-code" >constructor(private publikationService: PublikationService) { }</code>


&lt;h2&gt;{titel}&lt;/h2&gt;
<code class="mwt-code" >ngOnInit(): void {</code>


&lt;p&gt;{abstract}&lt;/p&gt;
<code class="mwt-code" >this.publikationService.getPublikationen().subscribe(data =</code>&gt;<code class="mwt-code" > {</code>


&lt;div&gt;{inhalt}&lt;/div&gt;
<code class="mwt-code" >this.publikationen = data;</code>


&lt;/div&gt;
<code class="mwt-code" >});</code>


);
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >}</code>


export default Publikation;
<span id="mein-erstes-angular-projekt-in-vscode"></span>
=== Mein erstes Angular Projekt in VSCode ===


'''Füge weitere Komponenten hinzu'''
<blockquote>Stellen wir zuerst sicher, dass Node.js auf deinem System installiert ist. Node.js kann von der [https://nodejs.org/ Node.js-Website] heruntergeladen und installieren werden.


Wir können nun weitere Komponenten erstellen, die beispielsweise das Kommentarformular und andere Teile der Anwendung zu integrieren. Zum Beispiel, erstelle src/KommentarFormular.js:
Installiere Angular CLI global, um ein neues Angular-Projekt zu erstellen:


import React, { useState } from 'react';
<code class="mwt-code" >npm install -g @angular/cli</code></blockquote>


function KommentarFormular() {
<span id="erstelle-ein-neues-angular-projekt"></span>
==== Erstelle ein neues Angular-Projekt ====


const [kommentar, setKommentar] = useState('');
<blockquote>Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll.


const handleChange = (event) =&gt; {
Führe den folgenden Befehl aus, um ein neues Angular-Projekt zu erstellen:


setKommentar(event.target.value);
<code class="mwt-code" >ng new from-peer-review-to-crowd-review</code>


};
Wähle &quot;Ja&quot; um Angular Routing zu verwenden und verwende das Standard-Stilformat (z. B. CSS).</blockquote>


const handleSubmit = (event) =&gt; {
<span id="öffne-das-projekt-in-visual-studio-code"></span>
==== Öffne das Projekt in Visual Studio Code ====


event.preventDefault();
Starte Visual Studio Code und öffne das Projektverzeichnis:


alert('Kommentar hinzugefügt: ' + kommentar);
<blockquote><code class="mwt-code" >code from-peer-review-to-crowd-review</code></blockquote>


setKommentar('');
<span id="erstelle-eine-komponente-für-die-publikation"></span>
==== Erstelle eine Komponente für die Publikation ====


};
Erstelle eine neue Komponente für die Publikationen:


return (
<blockquote><code class="mwt-code" >ng generate component publication</code></blockquote>
'''HTML-Datei (src/app/publikation/publikation.component.html):'''


&lt;form onSubmit={handleSubmit}&gt;
&lt;<code class="mwt-code" >div</code>&gt;


&lt;textarea
&lt;<code class="mwt-code" >h2</code>&gt;{{ titel }}&lt;<code class="mwt-code" >/h2</code>&gt;


value={kommentar}
&lt;<code class="mwt-code" >p</code>&gt;{{ abstract }}&lt;<code class="mwt-code" >/p</code>&gt;


onChange={handleChange}
&lt;<code class="mwt-code" >div</code>&gt;{{ inhalt }}&lt;<code class="mwt-code" >/div</code>&gt;


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
&lt;<code class="mwt-code" >/div</code>&gt;


/&gt;
'''TypeScript-Datei (src/app/publikation/publikation.component.ts):'''


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >import { Component, Input } from '@angular/core';</code>


&lt;/form&gt;
<code class="mwt-code" >@Component({</code>


);
<code class="mwt-code" >selector: 'app-publikation',</code>


}
<code class="mwt-code" >templateUrl: './publikation.component.html',</code>


export default KommentarFormular;
<code class="mwt-code" >styleUrls: ['./publikation.component.css']</code>


Importiere und verwende diese Komponente in App.js.
<code class="mwt-code" >})</code>


<span id="angular"></span>
<code class="mwt-code" >export class PublikationComponent {</code>
== Angular ==


Angular ist ein weit verbreitetes Framework für die Entwicklung von Webanwendungen, das von Google entwickelt wird. Es basiert auf TypeScript und bietet eine strukturierte Architektur für den Aufbau von Single-Page-Anwendungen. Angular nutzt Komponenten als grundlegende Bausteine für die Benutzeroberfläche und bietet eine Vielzahl von Funktionen wie Datenbindung, Dependency Injection und Routing, um die Entwicklung und Wartung von komplexen Anwendungen zu erleichtern. Es enthält auch ein leistungsstarkes CLI (Command Line Interface) zum Generieren von Code und zur Verwaltung von Projekten. Angular ist bekannt für seine umfassenden Features und seine robuste Architektur, die es für große und skalierbare Projekte geeignet macht.
<code class="mwt-code" >@Input() titel: string;</code>


<span id="komponenten-1"></span>
<code class="mwt-code" >@Input() abstract: string;</code>
=== Komponenten ===


In Angular sind Komponenten die Hauptbausteine der Benutzeroberfläche. Jede Komponente besteht aus einer HTML-Vorlage, einer CSS-Datei für das Styling und einer TypeScript-Datei für die Logik.
<code class="mwt-code" >@Input() inhalt: string;</code>


'''Beispiel:''' Erstellen wir eine PublikationComponent, um eine Publikation anzuzeigen.
<code class="mwt-code" >}</code>


'''HTML-Datei (publikation.component.html):'''
<span id="erstelle-eine-komponente-für-das-kommentarformular"></span>
==== Erstelle eine Komponente für das Kommentarformular ====


&lt;div&gt;
Erstelle eine neue Komponente für das Kommentarformular:


&lt;h2&gt;{{ titel }}&lt;/h2&gt;
<blockquote><code class="mwt-code" >ng generate component kommentar-formular</code></blockquote>
'''HTML-Datei (src/app/kommentar-formular/kommentar-formular.component.html):'''


&lt;p&gt;{{ abstract }}&lt;/p&gt;
&lt;<code class="mwt-code" >form (ngSubmit)=</code>&quot;<code class="mwt-code" >onSubmit()</code>&quot;<code class="mwt-code" > #kommentarForm=</code>&quot;<code class="mwt-code" >ngForm</code>&quot;&gt;


&lt;div&gt;{{ inhalt }}&lt;/div&gt;
&lt;<code class="mwt-code" >textarea</code>


&lt;/div&gt;
<code class="mwt-code" >name=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;


'''TypeScript-Datei (publikation.component.ts):'''
<code class="mwt-code" >[(ngModel)]=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;


import { Component, Input } from '@angular/core';
<code class="mwt-code" >placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;


@Component({
<code class="mwt-code" >required</code>&gt;


selector: 'app-publikation',
&lt;<code class="mwt-code" >/textarea</code>&gt;


templateUrl: './publikation.component.html',
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


styleUrls: ['./publikation.component.css']
&lt;<code class="mwt-code" >/form</code>&gt;


})
'''TypeScript-Datei (src/app/kommentar-formular/kommentar-formular.component.ts):'''


export class PublikationComponent {
<code class="mwt-code" >import { Component } from '@angular/core';</code>


@Input() titel: string;
<code class="mwt-code" >@Component({</code>


@Input() abstract: string;
<code class="mwt-code" >selector: 'app-kommentar-formular',</code>


@Input() inhalt: string;
<code class="mwt-code" >templateUrl: './kommentar-formular.component.html',</code>


}
<code class="mwt-code" >styleUrls: ['./kommentar-formular.component.css']</code>


<span id="module-1"></span>
<code class="mwt-code" >})</code>
=== Module ===


Angular-Anwendungen bestehen aus Modulen, die verschiedene Teile der Anwendung gruppieren. Ein Modul kann Komponenten, Dienste und andere Module enthalten.
<code class="mwt-code" >export class KommentarFormularComponent {</code>


'''Beispiel:''' Definieren wir ein Modul für die Publikationsfunktionalität.
<code class="mwt-code" >kommentar: string = '';</code>


'''TypeScript-Datei (app.module.ts):'''
<code class="mwt-code" >onSubmit(): void {</code>


import { NgModule } from '@angular/core';
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + this.kommentar);</code>


import { BrowserModule } from '@angular/platform-browser';
<code class="mwt-code" >this.kommentar = '';</code>


import { AppComponent } from './app.component';
<code class="mwt-code" >}</code>


import { PublikationComponent } from './publikation/publikation.component';
<code class="mwt-code" >}</code>


@NgModule({
<span id="füge-routing-hinzu"></span>
==== Füge Routing hinzu ====


declarations: [
'''TypeScript-Datei (src/app/app-routing.module.ts):'''


AppComponent,
<code class="mwt-code" >import { NgModule } from '@angular/core';</code>


PublikationComponent
<code class="mwt-code" >import { RouterModule, Routes } from '@angular/router';</code>


],
<code class="mwt-code" >import { PublikationComponent } from './publikation/publikation.component';</code>


imports: [
<code class="mwt-code" >import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';</code>


BrowserModule
<code class="mwt-code" >const routes: Routes = [</code>


],
<code class="mwt-code" >{ path: 'publikationen', component: PublikationComponent },</code>


providers: [],
<code class="mwt-code" >{ path: '', redirectTo: '/publikationen', pathMatch: 'full' }</code>


bootstrap: [AppComponent]
<code class="mwt-code" >];</code>


})
<code class="mwt-code" >@NgModule({</code>


export class AppModule { }
<code class="mwt-code" >imports: [RouterModule.forRoot(routes)],</code>


<span id="services"></span>
<code class="mwt-code" >exports: [RouterModule]</code>
=== Services ===


Services sind wiederverwendbare Klassen, die Logik und Datenmanagement bereitstellen. Sie werden oft verwendet, um Daten zwischen Komponenten zu teilen.
<code class="mwt-code" >})</code>


'''Beispiel:''' Erstellen wir nun einen PublikationService, um Publikationen von einer API abzurufen.
<code class="mwt-code" >export class AppRoutingModule { }</code>


'''TypeScript-Datei (publikation.service.ts):'''
'''TypeScript-Datei (src/app/app.module.ts):''' Füge die neuen Komponenten und das FormsModule hinzu:


import { Injectable } from '@angular/core';
<blockquote><code class="mwt-code" >import { NgModule } from '@angular/core';</code>


import { HttpClient } from '@angular/common/http';
<code class="mwt-code" >import { BrowserModule } from '@angular/platform-browser';</code>


import { Observable } from 'rxjs';
<code class="mwt-code" >import { FormsModule } from '@angular/forms'; // Importiere FormsModule</code>


@Injectable({
<code class="mwt-code" >import { AppComponent } from './app.component';</code>


providedIn: 'root'
<code class="mwt-code" >import { PublikationComponent } from './publikation/publikation.component';</code>


})
<code class="mwt-code" >import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';</code>


export class PublikationService {
<code class="mwt-code" >import { AppRoutingModule } from './app-routing.module';</code>


private apiUrl = 'https://api.example.com/publikationen';
<code class="mwt-code" >@NgModule({</code>


constructor(private http: HttpClient) { }
<code class="mwt-code" >declarations: [</code>


getPublikationen(): Observable&lt;any[]&gt; {
<code class="mwt-code" >AppComponent,</code>


return this.http.get&lt;any[]&gt;(this.apiUrl);
<code class="mwt-code" >PublikationComponent,</code>


}
<code class="mwt-code" >KommentarFormularComponent</code>


}
<code class="mwt-code" >],</code>


<span id="routing"></span>
<code class="mwt-code" >imports: [</code>
=== Routing ===


Angular-Routing ermöglicht das Navigieren zwischen verschiedenen Ansichten oder Komponenten innerhalb einer Anwendung.
<code class="mwt-code" >BrowserModule,</code>


'''Beispiel:''' Konfigurieren wir Routen für die Publikationsansicht und ein Kommentarformular.
<code class="mwt-code" >AppRoutingModule,</code>


'''TypeScript-Datei (app-routing.module.ts):'''
<code class="mwt-code" >FormsModule // Füge FormsModule hinzu</code>


import { NgModule } from '@angular/core';
<code class="mwt-code" >],</code>


import { RouterModule, Routes } from '@angular/router';
<code class="mwt-code" >providers: [],</code>


import { PublikationComponent } from './publikation/publikation.component';
<code class="mwt-code" >bootstrap: [AppComponent]</code>


const routes: Routes = [
<code class="mwt-code" >})</code>


{ path: 'publikationen', component: PublikationComponent },
<code class="mwt-code" >export class AppModule { }</code></blockquote>


{ path: '', redirectTo: '/publikationen', pathMatch: 'full' }
<span id="starte-die-anwendung"></span>
==== Starte die Anwendung ====


];
Starte den Angular-Entwicklungsserver, um deine Anwendung auszuführen:


@NgModule({
<blockquote><code class="mwt-code" >ng serve</code></blockquote>
Öffne einen Webbrowser und gehe zu http://localhost:4200, um die Anwendung zu sehen.


imports: [RouterModule.forRoot(routes)],
<span id="verändere-die-app.component.html"></span>
=== Verändere die app.component.html ===


exports: [RouterModule]
'''HTML-Datei (src/app/app.component.html):''' Ersetze den Standardinhalt, um die PublikationComponent und KommentarFormularComponent&nbsp;einzuschließen:


})
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >app</code>&quot;&gt;


export class AppRoutingModule { }
&lt;<code class="mwt-code" >h1</code>&gt;<code class="mwt-code" >Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code" >/h1</code>&gt;


<span id="datenbindung"></span>
&lt;<code class="mwt-code" >app-publikation</code>
=== Datenbindung ===


Angular bietet verschiedene Arten der Datenbindung, einschließlich Einweg- und Zweiweg-Datenbindung, um Daten zwischen der Logik der Komponente und der Ansicht zu synchronisieren.
<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >Gibt es die Matrix wirklich?</code>&quot;


'''Beispiel:''' Zeigen wir nun Daten aus dem PublikationService in der PublikationComponent an.
<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >Eine Untersuchung der Realität und ihrer Möglichkeiten.</code>&quot;


'''TypeScript-Datei (publikation.component.ts):'''
<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.</code>&quot;&gt;


import { Component, OnInit } from '@angular/core';
&lt;<code class="mwt-code" >/app-publikation</code>&gt;


import { PublikationService } from '../publikation.service';
&lt;<code class="mwt-code" >app-kommentar-formular</code>&gt;&lt;<code class="mwt-code" >/app-kommentar-formular</code>&gt;


@Component({
&lt;<code class="mwt-code" >/div</code>&gt;


selector: 'app-publikation',
Nun haben wir eine grundlegende Angular-Anwendung erstellt, die eine Publikation anzeigt und ein Kommentarformular enthält. Diese Anwendung verwendet grundlegende Angular-Konzepte wie Komponenten, Module, Routing und Formulare.


templateUrl: './publikation.component.html',
<span id="vue.js"></span>
== Vue.js ==


styleUrls: ['./publikation.component.css']
Vue.js ist besonders für seine Einfachheit und Flexibilität bekannt. Vue.js verwendet eine deklarative Syntax, bei der die Benutzeroberfläche mit einem reaktiven Datenmodell verknüpft ist, was bedeutet, dass sich die UI automatisch aktualisiert, wenn sich die zugrunde liegenden Daten ändern. Es basiert auf Komponenten, die HTML, CSS und JavaScript in einer einzigen Datei kombinieren, was die Entwicklung und Wartung von Anwendungen erleichtert. Vue.js ist leichtgewichtig, leicht erlernbar und lässt sich gut in bestehende Projekte integrieren oder für die Entwicklung von neuen, komplexeren Anwendungen nutzen.


})
<span id="komponenten-2"></span>
=== Komponenten ===


export class PublikationComponent implements OnInit {
In Vue.js sind Komponenten wiederverwendbare und isolierte Einheiten, die HTML, CSS und JavaScript zusammenfassen.


publikationen: any[] = [];
'''Beispiel:''' Erstellen wir eine Publikation-Komponente, um eine Publikation darzustellen.


constructor(private publikationService: PublikationService) { }
'''Datei Publikation.vue:'''


ngOnInit(): void {
&lt;<code class="mwt-code" >template</code>&gt;


this.publikationService.getPublikationen().subscribe(data =&gt; {
&lt;<code class="mwt-code" >div</code>&gt;


this.publikationen = data;
&lt;<code class="mwt-code" >h2</code>&gt;{{ titel }}&lt;<code class="mwt-code" >/h2</code>&gt;


});
&lt;<code class="mwt-code" >p</code>&gt;{{ abstract }}&lt;<code class="mwt-code" >/p</code>&gt;


}
&lt;<code class="mwt-code" >div</code>&gt;{{ inhalt }}&lt;<code class="mwt-code" >/div</code>&gt;


}
&lt;<code class="mwt-code" >/div</code>&gt;


<span id="forms"></span>
&lt;<code class="mwt-code" >/template</code>&gt;
=== Forms ===


Angular bietet sowohl Template-driven Forms als auch Reactive Forms für die Verarbeitung von Benutzereingaben.
&lt;<code class="mwt-code" >script</code>&gt;


'''Beispiel:''' Erstellen wir ein Formular zum Hinzufügen von Kommentaren.
<code class="mwt-code" >export default {</code>


'''HTML-Datei (kommentar-formular.component.html):'''
<code class="mwt-code" >props: {</code>


&lt;form (ngSubmit)=&quot;onSubmit()&quot; #kommentarForm=&quot;ngForm&quot;&gt;
<code class="mwt-code" >titel: String,</code>


&lt;textarea
<code class="mwt-code" >abstract: String,</code>


name=&quot;kommentar&quot;
<code class="mwt-code" >inhalt: String</code>


[(ngModel)]=&quot;kommentar&quot;
<code class="mwt-code" >}</code>


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
<code class="mwt-code" >}</code>


required&gt;
&lt;<code class="mwt-code" >/script</code>&gt;


&lt;/textarea&gt;
&lt;<code class="mwt-code" >style scoped</code>&gt;


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >/* Styles für die Publikation */</code>


&lt;/form&gt;
&lt;<code class="mwt-code" >/style</code>&gt;


'''TypeScript-Datei (kommentar-formular.component.ts):'''
<span id="reaktive-datenbindung"></span>
=== Reaktive Datenbindung ===


import { Component } from '@angular/core';
Vue.js verwendet reaktive Datenbindung, um sicherzustellen, dass Änderungen an Daten automatisch in der Benutzeroberfläche angezeigt werden.


@Component({
'''Beispiel:''' Verwenden wir eine data-Eigenschaft in einer App-Komponente, um eine Liste von Publikationen zu verwalten.


selector: 'app-kommentar-formular',
'''Datei App.vue:'''


templateUrl: './kommentar-formular.component.html',
&lt;<code class="mwt-code" >template</code>&gt;


styleUrls: ['./kommentar-formular.component.css']
&lt;<code class="mwt-code" >div id=</code>&quot;<code class="mwt-code" >app</code>&quot;&gt;


})
&lt;<code class="mwt-code" >h1</code>&gt;<code class="mwt-code" >Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code" >/h1</code>&gt;


export class KommentarFormularComponent {
&lt;<code class="mwt-code" >Publikation</code>


kommentar: string = '';
<code class="mwt-code" >v-for=</code>&quot;<code class="mwt-code" >(publikation, index) in publikationen</code>&quot;


onSubmit(): void {
:<code class="mwt-code" >key=</code>&quot;<code class="mwt-code" >index</code>&quot;
:<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >publikation.titel</code>&quot;
:<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >publikation.abstract</code>&quot;
:<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >publikation.inhalt</code>&quot;
<code class="mwt-code" >/</code>&gt;


alert('Kommentar hinzugefügt: ' + this.kommentar);
&lt;<code class="mwt-code" >KommentarFormular /</code>&gt;


this.kommentar = '';
&lt;<code class="mwt-code" >/div</code>&gt;


}
&lt;<code class="mwt-code" >/template</code>&gt;


}
&lt;<code class="mwt-code" >script</code>&gt;


<span id="dependency-injection"></span>
<code class="mwt-code" >import Publikation from './components/Publikation.vue';</code>
=== Dependency Injection ===


Angular verwendet Dependency Injection (DI), um Abhängigkeiten wie Services in Komponenten und andere Services einzufügen.
<code class="mwt-code" >import KommentarFormular from './components/KommentarFormular.vue';</code>


'''Beispiel:''' Der PublikationService wird in PublikationComponent durch DI eingefügt.
<code class="mwt-code" >export default {</code>


'''TypeScript-Datei (publikation.component.ts):'''
<code class="mwt-code" >components: {</code>


import { Component, OnInit } from '@angular/core';
<code class="mwt-code" >Publikation,</code>


import { PublikationService } from '../publikation.service';
<code class="mwt-code" >KommentarFormular</code>


@Component({
<code class="mwt-code" >},</code>


selector: 'app-publikation',
<code class="mwt-code" >data() {</code>


templateUrl: './publikation.component.html',
<code class="mwt-code" >return {</code>


styleUrls: ['./publikation.component.css']
<code class="mwt-code" >publikationen: [</code>


})
<code class="mwt-code" >{</code>


export class PublikationComponent implements OnInit {
<code class="mwt-code" >titel: 'Gibt es die Matrix wirklich?',</code>


publikationen: any[] = [];
<code class="mwt-code" >abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',</code>


constructor(private publikationService: PublikationService) { }
<code class="mwt-code" >inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'</code>


ngOnInit(): void {
<code class="mwt-code" >}</code>


this.publikationService.getPublikationen().subscribe(data =&gt; {
<code class="mwt-code" >]</code>


this.publikationen = data;
<code class="mwt-code" >}</code>


});
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >}</code>


}
&lt;<code class="mwt-code" >/script</code>&gt;


<span id="mein-erstes-angular-projekt-in-vscode"></span>
&lt;<code class="mwt-code" >style</code>&gt;
=== Mein erstes Angular Projekt in VSCode ===


<blockquote>Stellen wir zuerst sicher, dass Node.js auf deinem System installiert ist. Node.js kann von der [https://nodejs.org/ Node.js-Website] heruntergeladen und installieren werden.
<code class="mwt-code" >/* Styles für die App */</code>


Installiere Angular CLI global, um ein neues Angular-Projekt zu erstellen:
&lt;<code class="mwt-code" >/style</code>&gt;


npm install -g @angular/cli
<span id="props-1"></span>
</blockquote>
=== Props ===
<span id="erstelle-ein-neues-angular-projekt"></span>
==== Erstelle ein neues Angular-Projekt ====


<blockquote>Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll.
Props sind Eigenschaften, die von einer übergeordneten Komponente an eine untergeordnete Komponente übergeben werden, um Daten zu übermitteln.


Führe den folgenden Befehl aus, um ein neues Angular-Projekt zu erstellen:
'''Beispiel:''' Die Publikation-Komponente erhält titel, abstract und inhalt&nbsp;als Props.


ng new from-peer-review-to-crowd-review
'''In Publikation.vue:'''


Wähle &quot;Ja&quot; um Angular Routing zu verwenden und verwende das Standard-Stilformat (z. B. CSS).
&lt;<code class="mwt-code" >template</code>&gt;
</blockquote>
<span id="öffne-das-projekt-in-visual-studio-code"></span>
==== Öffne das Projekt in Visual Studio Code ====


Starte Visual Studio Code und öffne das Projektverzeichnis:
&lt;<code class="mwt-code" >div</code>&gt;


<blockquote>code from-peer-review-to-crowd-review
&lt;<code class="mwt-code" >h2</code>&gt;{{ titel }}&lt;<code class="mwt-code" >/h2</code>&gt;
</blockquote>
<span id="erstelle-eine-komponente-für-die-publikation"></span>
==== Erstelle eine Komponente für die Publikation ====


Erstelle eine neue Komponente für die Publikationen:
&lt;<code class="mwt-code" >p</code>&gt;{{ abstract }}&lt;<code class="mwt-code" >/p</code>&gt;


<blockquote>ng generate component publication
&lt;<code class="mwt-code" >div</code>&gt;{{ inhalt }}&lt;<code class="mwt-code" >/div</code>&gt;
</blockquote>
'''HTML-Datei (src/app/publikation/publikation.component.html):'''


&lt;div&gt;
&lt;<code class="mwt-code" >/div</code>&gt;


&lt;h2&gt;{{ titel }}&lt;/h2&gt;
&lt;<code class="mwt-code" >/template</code>&gt;


&lt;p&gt;{{ abstract }}&lt;/p&gt;
&lt;<code class="mwt-code" >script</code>&gt;


&lt;div&gt;{{ inhalt }}&lt;/div&gt;
<code class="mwt-code" >export default {</code>


&lt;/div&gt;
<code class="mwt-code" >props: {</code>


'''TypeScript-Datei (src/app/publikation/publikation.component.ts):'''
<code class="mwt-code" >titel: String,</code>


import { Component, Input } from '@angular/core';
<code class="mwt-code" >abstract: String,</code>


@Component({
<code class="mwt-code" >inhalt: String</code>


selector: 'app-publikation',
<code class="mwt-code" >}</code>


templateUrl: './publikation.component.html',
<code class="mwt-code" >}</code>


styleUrls: ['./publikation.component.css']
&lt;<code class="mwt-code" >/script</code>&gt;


})
<span id="event-handling-1"></span>
=== Event Handling ===


export class PublikationComponent {
Vue.js ermöglicht es, Benutzeraktionen wie Klicks und Eingaben zu erfassen und darauf zu reagieren.


@Input() titel: string;
'''Beispiel:''' Erstellen wir nun ein Kommentarformular, das einen Kommentar hinzufügt und anzeigt.


@Input() abstract: string;
'''Datei''' KommentarFormular.vue''':'''


@Input() inhalt: string;
&lt;<code class="mwt-code" >template</code>&gt;


}
&lt;<code class="mwt-code" >form @submit.prevent=</code>&quot;<code class="mwt-code" >onSubmit</code>&quot;&gt;


<span id="erstelle-eine-komponente-für-das-kommentarformular"></span>
&lt;<code class="mwt-code" >textarea v-model=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;<code class="mwt-code" > placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;<code class="mwt-code" > required</code>&gt;&lt;<code class="mwt-code" >/textarea</code>&gt;
==== Erstelle eine Komponente für das Kommentarformular ====


Erstelle eine neue Komponente für das Kommentarformular:
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


<blockquote>ng generate component kommentar-formular
&lt;<code class="mwt-code" >/form</code>&gt;
</blockquote>
'''HTML-Datei (src/app/kommentar-formular/kommentar-formular.component.html):'''


&lt;form (ngSubmit)=&quot;onSubmit()&quot; #kommentarForm=&quot;ngForm&quot;&gt;
&lt;<code class="mwt-code" >/template</code>&gt;


&lt;textarea
&lt;<code class="mwt-code" >script</code>&gt;


name=&quot;kommentar&quot;
<code class="mwt-code" >export default {</code>


[(ngModel)]=&quot;kommentar&quot;
<code class="mwt-code" >data() {</code>


placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot;
<code class="mwt-code" >return {</code>


required&gt;
<code class="mwt-code" >kommentar: ''</code>


&lt;/textarea&gt;
<code class="mwt-code" >}</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >},</code>


&lt;/form&gt;
<code class="mwt-code" >methods: {</code>


'''TypeScript-Datei (src/app/kommentar-formular/kommentar-formular.component.ts):'''
<code class="mwt-code" >onSubmit() {</code>


import { Component } from '@angular/core';
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + this.kommentar);</code>


@Component({
<code class="mwt-code" >this.kommentar = '';</code>


selector: 'app-kommentar-formular',
<code class="mwt-code" >}</code>


templateUrl: './kommentar-formular.component.html',
<code class="mwt-code" >}</code>


styleUrls: ['./kommentar-formular.component.css']
<code class="mwt-code" >}</code>


})
&lt;<code class="mwt-code" >/script</code>&gt;


export class KommentarFormularComponent {
&lt;<code class="mwt-code" >style scoped</code>&gt;


kommentar: string = '';
<code class="mwt-code" >/* Styles für das Kommentarformular */</code>


onSubmit(): void {
&lt;<code class="mwt-code" >/style</code>&gt;


alert('Kommentar hinzugefügt: ' + this.kommentar);
<span id="vue-router"></span>
=== Vue Router ===


this.kommentar = '';
Vue Router ist eine offizielle Router-Bibliothek für Vue.js, die das Routing innerhalb der Anwendung ermöglicht.


}
'''Beispiel:''' Konfigurieren wir nun Routen, um zwischen verschiedenen Komponenten zu navigieren.


}
'''Datei''' router/index.js''':'''


<span id="füge-routing-hinzu"></span>
<code class="mwt-code" >import Vue from 'vue';</code>
==== Füge Routing hinzu ====


'''TypeScript-Datei (src/app/app-routing.module.ts):'''
<code class="mwt-code" >import Router from 'vue-router';</code>


import { NgModule } from '@angular/core';
<code class="mwt-code" >import Publikation from '../components/Publikation.vue';</code>


import { RouterModule, Routes } from '@angular/router';
<code class="mwt-code" >import KommentarFormular from '../components/KommentarFormular.vue';</code>


import { PublikationComponent } from './publikation/publikation.component';
<code class="mwt-code" >Vue.use(Router);</code>


import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';
<code class="mwt-code" >export default new Router({</code>


const routes: Routes = [
<code class="mwt-code" >routes: [</code>


{ path: 'publikationen', component: PublikationComponent },
<code class="mwt-code" >{</code>


{ path: '', redirectTo: '/publikationen', pathMatch: 'full' }
<code class="mwt-code" >path: '/publikationen',</code>


];
<code class="mwt-code" >name: 'Publikation',</code>


@NgModule({
<code class="mwt-code" >component: Publikation</code>


imports: [RouterModule.forRoot(routes)],
<code class="mwt-code" >},</code>


exports: [RouterModule]
<code class="mwt-code" >{</code>


})
<code class="mwt-code" >path: '/',</code>


export class AppRoutingModule { }
<code class="mwt-code" >name: 'KommentarFormular',</code>


'''TypeScript-Datei (src/app/app.module.ts):''' Füge die neuen Komponenten und das FormsModule hinzu:
<code class="mwt-code" >component: KommentarFormular</code>


<blockquote>import { NgModule } from '@angular/core';
<code class="mwt-code" >}</code>


import { BrowserModule } from '@angular/platform-browser';
<code class="mwt-code" >]</code>


import { FormsModule } from '@angular/forms'; // Importiere FormsModule
<code class="mwt-code" >});</code>


import { AppComponent } from './app.component';
'''In der Hauptdatei''' main.js''':'''


import { PublikationComponent } from './publikation/publikation.component';
<code class="mwt-code" >import Vue from 'vue';</code>


import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';
<code class="mwt-code" >import App from './App.vue';</code>


import { AppRoutingModule } from './app-routing.module';
<code class="mwt-code" >import router from './router';</code>


@NgModule({
<code class="mwt-code" >Vue.config.productionTip = false;</code>


declarations: [
<code class="mwt-code" >new Vue({</code>


AppComponent,
<code class="mwt-code" >router,</code>


PublikationComponent,
<code class="mwt-code" >render: h =</code>&gt;<code class="mwt-code" > h(App)</code>


KommentarFormularComponent
<code class="mwt-code" >}).$mount('#app');</code>


],
<span id="vuex"></span>
=== Vuex ===


imports: [
Vuex ist eine State-Management-Bibliothek für Vue.js-Anwendungen, die ein zentrales Repository für alle Komponenten bereitstellt.


BrowserModule,
'''Beispiel:''' Verwende Vuex für die Verwaltung der Publikationen.


AppRoutingModule,
'''Datei''' store/index.js''':'''


FormsModule // Füge FormsModule hinzu
<code class="mwt-code" >import Vue from 'vue';</code>


],
<code class="mwt-code" >import Vuex from 'vuex';</code>


providers: [],
<code class="mwt-code" >Vue.use(Vuex);</code>


bootstrap: [AppComponent]
<code class="mwt-code" >export default new Vuex.Store({</code>


})
<code class="mwt-code" >state: {</code>


export class AppModule { }
<code class="mwt-code" >publikationen: [</code>
</blockquote>
<span id="starte-die-anwendung"></span>
==== Starte die Anwendung ====


Starte den Angular-Entwicklungsserver, um deine Anwendung auszuführen:
<code class="mwt-code" >{</code>


<blockquote>ng serve
<code class="mwt-code" >titel: 'Gibt es die Matrix wirklich?',</code>
</blockquote>
Öffne einen Webbrowser und gehe zu http://localhost:4200, um die Anwendung zu sehen.


<span id="verändere-die-app.component.html"></span>
<code class="mwt-code" >abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',</code>
=== Verändere die app.component.html ===


'''HTML-Datei (src/app/app.component.html):''' Ersetze den Standardinhalt, um die PublikationComponent und KommentarFormularComponent einzuschließen:
<code class="mwt-code" >inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'</code>


&lt;div class=&quot;app&quot;&gt;
<code class="mwt-code" >}</code>


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
<code class="mwt-code" >]</code>


&lt;app-publikation
<code class="mwt-code" >},</code>


titel=&quot;Gibt es die Matrix wirklich?&quot;
<code class="mwt-code" >mutations: {</code>


abstract=&quot;Eine Untersuchung der Realität und ihrer Möglichkeiten.&quot;
<code class="mwt-code" >addPublikation(state, publikationen) {</code>


inhalt=&quot;Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.&quot;&gt;
<code class="mwt-code" >state.publikationen.push(publikationen);</code>


&lt;/app-publikation&gt;
<code class="mwt-code" >}</code>


&lt;app-kommentar-formular&gt;&lt;/app-kommentar-formular&gt;
<code class="mwt-code" >},</code>


&lt;/div&gt;
<code class="mwt-code" >actions: {</code>


Nun haben wir eine grundlegende Angular-Anwendung erstellt, die eine Publikation anzeigt und ein Kommentarformular enthält. Diese Anwendung verwendet grundlegende Angular-Konzepte wie Komponenten, Module, Routing und Formulare.
<code class="mwt-code" >addPublikation({ commit }, publikationen) {</code>


<span id="vue.js"></span>
<code class="mwt-code" >commit('addPublikation', publikationen);</code>
== Vue.js ==


Vue.js ist besonders für seine Einfachheit und Flexibilität bekannt. Vue.js verwendet eine deklarative Syntax, bei der die Benutzeroberfläche mit einem reaktiven Datenmodell verknüpft ist, was bedeutet, dass sich die UI automatisch aktualisiert, wenn sich die zugrunde liegenden Daten ändern. Es basiert auf Komponenten, die HTML, CSS und JavaScript in einer einzigen Datei kombinieren, was die Entwicklung und Wartung von Anwendungen erleichtert. Vue.js ist leichtgewichtig, leicht erlernbar und lässt sich gut in bestehende Projekte integrieren oder für die Entwicklung von neuen, komplexeren Anwendungen nutzen.
<code class="mwt-code" >}</code>


<span id="komponenten-2"></span>
<code class="mwt-code" >}</code>
=== Komponenten ===


In Vue.js sind Komponenten wiederverwendbare und isolierte Einheiten, die HTML, CSS und JavaScript zusammenfassen.
<code class="mwt-code" >});</code>


'''Beispiel:''' Erstellen wir eine Publikation-Komponente, um eine Publikation darzustellen.
'''In''' App.vue''':'''


'''Datei Publikation.vue:'''
&lt;<code class="mwt-code" >template</code>&gt;


&lt;template&gt;
&lt;<code class="mwt-code" >div id=</code>&quot;<code class="mwt-code" >app</code>&quot;&gt;


&lt;div&gt;
&lt;<code class="mwt-code" >h1</code>&gt;<code class="mwt-code" >Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code" >/h1</code>&gt;


&lt;h2&gt;{{ titel }}&lt;/h2&gt;
&lt;<code class="mwt-code" >Publikation</code>


&lt;p&gt;{{ abstract }}&lt;/p&gt;
<code class="mwt-code" >v-for=</code>&quot;<code class="mwt-code" >(publikation, index) in $store.state.publikationen</code>&quot;


&lt;div&gt;{{ inhalt }}&lt;/div&gt;
:<code class="mwt-code" >key=</code>&quot;<code class="mwt-code" >index</code>&quot;
:<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >publikation.titel</code>&quot;
:<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >publikation.abstract</code>&quot;
:<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >publikation.inhalt</code>&quot;
<code class="mwt-code" >/</code>&gt;


&lt;/div&gt;
&lt;<code class="mwt-code" >KommentarFormular /</code>&gt;


&lt;/template&gt;
&lt;<code class="mwt-code" >/div</code>&gt;


&lt;script&gt;
&lt;<code class="mwt-code" >/template</code>&gt;


export default {
Mit diesen Konzepten kann man strukturierte Vue.js-Anwendung erstellen, die eine Publikation anzeigt und ein Kommentarformular enthält.


props: {
<span id="mein-erstes-vue.js-projekt-in-vscode"></span>
=== Mein erstes Vue.js Projekt in VSCode ===


titel: String,
Es beginnt wieder damit sicherzustellen, dass Node.js auf deinem System installiert ist. Falls nicht, lade es von der [https://nodejs.org/ Node.js-Website] herunter und installiere es.


abstract: String,
Installiere Vue CLI global, um ein neues Vue-Projekt zu erstellen:


inhalt: String
npm install -g @vue/cli


}
<span id="erstelle-ein-neues-vue-projekt"></span>
==== Erstelle ein neues Vue-Projekt ====


}
Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll. Führe den folgenden Befehl aus:


&lt;/script&gt;
vue create from-peer-review-to-crowd-review


&lt;style scoped&gt;
Wähle die Standardkonfiguration oder passe sie nach Bedarf an.


/* Styles für die Publikation */
<span id="öffne-das-projekt-in-visual-studio-code-1"></span>
==== Öffne das Projekt in Visual Studio Code ====


&lt;/style&gt;
Starte Visual Studio Code und öffne das neu erstellte Projektverzeichnis:


<span id="reaktive-datenbindung"></span>
code from-peer-review-to-crowd-review
=== Reaktive Datenbindung ===


Vue.js verwendet reaktive Datenbindung, um sicherzustellen, dass Änderungen an Daten automatisch in der Benutzeroberfläche angezeigt werden.
<span id="erstelle-komponenten"></span>
==== 4. Erstelle Komponenten ====


'''Beispiel:''' Verwenden wir eine data-Eigenschaft in einer App-Komponente, um eine Liste von Publikationen zu verwalten.
Erstelle eine neue Datei für die Publikation-Komponente:


'''Datei App.vue:'''
* Erstelle einen neuen Ordner components im src-Verzeichnis
* Füge eine Datei Publikation.vue im src/components-Ordner hinzu
'''Datei''' src/components/Publikation.vue''':'''


&lt;template&gt;
&lt;<code class="mwt-code" >template</code>&gt;


&lt;div id=&quot;app&quot;&gt;
&lt;<code class="mwt-code" >div</code>&gt;


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
&lt;<code class="mwt-code" >h2</code>&gt;{{ titel }}&lt;<code class="mwt-code" >/h2</code>&gt;


&lt;Publikation
&lt;<code class="mwt-code" >p</code>&gt;{{ abstract }}&lt;<code class="mwt-code" >/p</code>&gt;


v-for=&quot;(publikation, index) in publikationen&quot;
&lt;<code class="mwt-code" >div</code>&gt;{{ inhalt }}&lt;<code class="mwt-code" >/div</code>&gt;


:key=&quot;index&quot;
&lt;<code class="mwt-code" >/div</code>&gt;


:titel=&quot;publikation.titel&quot;
&lt;<code class="mwt-code" >/template</code>&gt;


:abstract=&quot;publikation.abstract&quot;
&lt;<code class="mwt-code" >script</code>&gt;


:inhalt=&quot;publikation.inhalt&quot;
<code class="mwt-code" >export default {</code>


/&gt;
<code class="mwt-code" >props: {</code>


&lt;KommentarFormular /&gt;
<code class="mwt-code" >titel: String,</code>


&lt;/div&gt;
<code class="mwt-code" >abstract: String,</code>


&lt;/template&gt;
<code class="mwt-code" >inhalt: String</code>


&lt;script&gt;
<code class="mwt-code" >}</code>


import Publikation from './components/Publikation.vue';
<code class="mwt-code" >}</code>


import KommentarFormular from './components/KommentarFormular.vue';
&lt;<code class="mwt-code" >/script</code>&gt;


export default {
&lt;<code class="mwt-code" >style scoped</code>&gt;


components: {
<code class="mwt-code" >/* Styles für die Publikation */</code>


Publikation,
&lt;<code class="mwt-code" >/style</code>&gt;


KommentarFormular
<code class="mwt-code" >Füge eine Datei KommentarFormular.vue im src/components-Ordner hinzu.</code>


},
<code class="mwt-code" >'''Datei''' src/components/KommentarFormular.vue''':'''</code>


data() {
&lt;<code class="mwt-code" >template</code>&gt;


return {
&lt;<code class="mwt-code" >form @submit.prevent=</code>&quot;<code class="mwt-code" >onSubmit</code>&quot;&gt;


publikationen: [
&lt;<code class="mwt-code" >textarea v-model=</code>&quot;<code class="mwt-code" >kommentar</code>&quot;<code class="mwt-code" > placeholder=</code>&quot;<code class="mwt-code" >Fügen Sie einen Kommentar hinzu...</code>&quot;<code class="mwt-code" > required</code>&gt;&lt;<code class="mwt-code" >/textarea</code>&gt;


{
&lt;<code class="mwt-code" >button type=</code>&quot;<code class="mwt-code" >submit</code>&quot;&gt;<code class="mwt-code" >Kommentar hinzufügen</code>&lt;<code class="mwt-code" >/button</code>&gt;


titel: 'Gibt es die Matrix wirklich?',
&lt;<code class="mwt-code" >/form</code>&gt;


abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',
&lt;<code class="mwt-code" >/template</code>&gt;


inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'
&lt;<code class="mwt-code" >script</code>&gt;


}
<code class="mwt-code" >export default {</code>


]
<code class="mwt-code" >data() {</code>


}
<code class="mwt-code" >return {</code>


}
<code class="mwt-code" >kommentar: ''</code>


}
<code class="mwt-code" >}</code>


&lt;/script&gt;
<code class="mwt-code" >},</code>


&lt;style&gt;
<code class="mwt-code" >methods: {</code>


/* Styles für die App */
<code class="mwt-code" >onSubmit() {</code>


&lt;/style&gt;
<code class="mwt-code" >alert('Kommentar hinzugefügt: ' + this.kommentar);</code>


<span id="props-1"></span>
<code class="mwt-code" >this.kommentar = '';</code>
=== Props ===


Props sind Eigenschaften, die von einer übergeordneten Komponente an eine untergeordnete Komponente übergeben werden, um Daten zu übermitteln.
<code class="mwt-code" >}</code>


'''Beispiel:''' Die Publikation-Komponente erhält titel, abstract und inhalt als Props.
<code class="mwt-code" >}</code>


'''In Publikation.vue:'''
<code class="mwt-code" >}</code>


&lt;template&gt;
&lt;<code class="mwt-code" >/script</code>&gt;


&lt;div&gt;
&lt;<code class="mwt-code" >style scoped</code>&gt;


&lt;h2&gt;{{ titel }}&lt;/h2&gt;
<code class="mwt-code" >/* Styles für das Kommentarformular */</code>


&lt;p&gt;{{ abstract }}&lt;/p&gt;
&lt;<code class="mwt-code" >/style</code>&gt;


&lt;div&gt;{{ inhalt }}&lt;/div&gt;
<span id="konfiguriere-routing"></span>
==== Konfiguriere Routing ====


&lt;/div&gt;
Falls das Projekt noch keinen Router enthält, installiere Vue Router:


&lt;/template&gt;
npm install vue-router


&lt;script&gt;
Erstelle eine Datei router/index.js im src-Verzeichnis:


export default {
'''Datei''' src/router/index.js''':'''


props: {
<code class="mwt-code" >import Vue from 'vue';</code>


titel: String,
<code class="mwt-code" >import Router from 'vue-router';</code>


abstract: String,
<code class="mwt-code" >import Publikation from '../components/Publikation.vue';</code>


inhalt: String
<code class="mwt-code" >import KommentarFormular from '../components/KommentarFormular.vue';</code>


}
<code class="mwt-code" >Vue.use(Router);</code>


}
<code class="mwt-code" >export default new Router({</code>


&lt;/script&gt;
<code class="mwt-code" >routes: [</code>


<span id="event-handling-1"></span>
<code class="mwt-code" >{</code>
=== Event Handling ===


Vue.js ermöglicht es, Benutzeraktionen wie Klicks und Eingaben zu erfassen und darauf zu reagieren.
<code class="mwt-code" >path: '/publikationen',</code>


'''Beispiel:''' Erstellen wir nun ein Kommentarformular, das einen Kommentar hinzufügt und anzeigt.
<code class="mwt-code" >name: 'Publikation',</code>


'''Datei''' KommentarFormular.vue''':'''
<code class="mwt-code" >component: Publikation</code>


&lt;template&gt;
<code class="mwt-code" >},</code>


&lt;form @submit.prevent=&quot;onSubmit&quot;&gt;
<code class="mwt-code" >{</code>


&lt;textarea v-model=&quot;kommentar&quot; placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot; required&gt;&lt;/textarea&gt;
<code class="mwt-code" >path: '/',</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
<code class="mwt-code" >name: 'KommentarFormular',</code>


&lt;/form&gt;
<code class="mwt-code" >component: KommentarFormular</code>


&lt;/template&gt;
<code class="mwt-code" >}</code>


&lt;script&gt;
<code class="mwt-code" >]</code>


export default {
<code class="mwt-code" >});</code>


data() {
<span id="verwende-die-komponenten-in-app.vue"></span>
==== Verwende die Komponenten in App.vue ====


return {
Ersetze den Inhalt der App.vue, um die Publikation- und KommentarFormular-Komponenten einzuschließen:


kommentar: ''
'''Datei''' src/App.vue''':'''


}
&lt;<code class="mwt-code" >template</code>&gt;


},
&lt;<code class="mwt-code" >div id=</code>&quot;<code class="mwt-code" >app</code>&quot;&gt;


methods: {
&lt;<code class="mwt-code" >h1</code>&gt;<code class="mwt-code" >Wissenschaftliche Publikationen</code>&lt;<code class="mwt-code" >/h1</code>&gt;


onSubmit() {
&lt;<code class="mwt-code" >Publikation</code>


alert('Kommentar hinzugefügt: ' + this.kommentar);
<code class="mwt-code" >v-for=</code>&quot;<code class="mwt-code" >(publikation, index) in publikationen</code>&quot;


this.kommentar = '';
:<code class="mwt-code" >key=</code>&quot;<code class="mwt-code" >index</code>&quot;
:<code class="mwt-code" >titel=</code>&quot;<code class="mwt-code" >publikation.titel</code>&quot;
:<code class="mwt-code" >abstract=</code>&quot;<code class="mwt-code" >publikation.abstract</code>&quot;
:<code class="mwt-code" >inhalt=</code>&quot;<code class="mwt-code" >publikation.inhalt</code>&quot;
<code class="mwt-code" >/</code>&gt;


}
&lt;<code class="mwt-code" >KommentarFormular /</code>&gt;


}
&lt;<code class="mwt-code" >/div</code>&gt;


}
&lt;<code class="mwt-code" >/template</code>&gt;


&lt;/script&gt;
&lt;<code class="mwt-code" >script</code>&gt;


&lt;style scoped&gt;
<code class="mwt-code" >import Publikation from './components/Publikation.vue';</code>


/* Styles für das Kommentarformular */
<code class="mwt-code" >import KommentarFormular from './components/KommentarFormular.vue';</code>


&lt;/style&gt;
<code class="mwt-code" >export default {</code>


<span id="vue-router"></span>
<code class="mwt-code" >components: {</code>
=== Vue Router ===


Vue Router ist eine offizielle Router-Bibliothek für Vue.js, die das Routing innerhalb der Anwendung ermöglicht.
<code class="mwt-code" >Publikation,</code>


'''Beispiel:''' Konfigurieren wir nun Routen, um zwischen verschiedenen Komponenten zu navigieren.
<code class="mwt-code" >KommentarFormular</code>


'''Datei''' router/index.js''':'''
<code class="mwt-code" >},</code>


import Vue from 'vue';
<code class="mwt-code" >data() {</code>


import Router from 'vue-router';
<code class="mwt-code" >return {</code>


import Publikation from '../components/Publikation.vue';
<code class="mwt-code" >publikationen: [</code>


import KommentarFormular from '../components/KommentarFormular.vue';
<code class="mwt-code" >{</code>


Vue.use(Router);
<code class="mwt-code" >titel: 'Gibt es die Matrix wirklich?',</code>


export default new Router({
<code class="mwt-code" >abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',</code>


routes: [
<code class="mwt-code" >inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'</code>


{
<code class="mwt-code" >}</code>


path: '/publikationen',
<code class="mwt-code" >]</code>


name: 'Publikation',
<code class="mwt-code" >}</code>


component: Publikation
<code class="mwt-code" >}</code>


},
<code class="mwt-code" >}</code>


{
&lt;<code class="mwt-code" >/script</code>&gt;


path: '/',
&lt;<code class="mwt-code" >style</code>&gt;


name: 'KommentarFormular',
<code class="mwt-code" >/* Styles für die App */</code>


component: KommentarFormular
&lt;<code class="mwt-code" >/style</code>&gt;


}
<span id="starte-die-anwendung-1"></span>
==== Starte die Anwendung ====


]
Starte den Vue-Entwicklungsserver, um die Anwendung auszuführen:


});
npm run serve


'''In der Hauptdatei''' main.js''':'''
Öffne einen Webbrowser und gehe zu http://localhost:8080, um die Anwendung zu sehen.


import Vue from 'vue';
Jetzt haben wir ein funktionierendes Vue.js-Projekt erstellt, welches eine Publikation anzeigt und ein Kommentarformular enthält.


import App from './App.vue';
<span id="asynchrone-programmierung-und-datenübertragung"></span>
= Asynchrone Programmierung und Datenübertragung =


import router from './router';
Frontend-Entwicklung konzentriert sich auf die Gestaltung der Benutzeroberfläche und Interaktivität einer Webanwendung unter Verwendung moderner Technologien wie HTML5, CSS3 und JavaScript-Frameworks wie React, Angular oder Vue.js. Im Full-Stack-Kontext arbeitet das Frontend mit dem Backend zusammen, das durch Technologien wie Node.js, Express und Datenbanken wie MongoDB oder PostgreSQL unterstützt wird. Die Kommunikation zwischen Frontend und Backend erfolgt typischerweise durch RESTful APIs oder GraphQL, wobei JSON oder XML als Formate für den Datenaustausch verwendet werden. Promises und async/await sind Methoden zur Handhabung von asynchronem Code in JavaScript. Sie helfen dabei, Code lesbarer und wartbarer zu machen, insbesondere wenn man mit asynchronen Operationen wie API-Anfragen oder Datenverarbeitung arbeitet.


Vue.config.productionTip = false;
Sehen wir uns nun an, wie man Promises und async/await in unserem Beispiel anwenden kann. Promises sind Objekte, die einen zukünftigen Wert repräsentieren. Sie bieten eine Möglichkeit, asynchrone Operationen zu verwalten, indem sie auf den Abschluss dieser Operation warten.


new Vue({
Angenommen, wir möchten die Publikationen von einem Server abrufen. Wir verwenden eine Funktion, die ein Promise zurückgibt:


router,
'''JavaScript Code:'''


render: h =&gt; h(App)
<code class="mwt-code" >// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)</code>


}).$mount('#app');
<code class="mwt-code" >function fetchPublikationen() {</code>


<span id="vuex"></span>
<code class="mwt-code" >return new Promise((resolve, reject) =</code>&gt;<code class="mwt-code" > {</code>
=== Vuex ===


Vuex ist eine State-Management-Bibliothek für Vue.js-Anwendungen, die ein zentrales Repository für alle Komponenten bereitstellt.
<code class="mwt-code" >setTimeout(() =</code>&gt;<code class="mwt-code" > {</code>


'''Beispiel:''' Verwende Vuex für die Verwaltung der Publikationen.
<code class="mwt-code" >const publikationen = [</code>


'''Datei''' store/index.js''':'''
<code class="mwt-code" >{</code>


import Vue from 'vue';
<code class="mwt-code" >titel: 'Gibt es die Matrix wirklich?',</code>


import Vuex from 'vuex';
<code class="mwt-code" >abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',</code>


Vue.use(Vuex);
<code class="mwt-code" >inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'</code>


export default new Vuex.Store({
<code class="mwt-code" >}</code>


state: {
<code class="mwt-code" >];</code>


publikationen: [
<code class="mwt-code" >resolve(publikationen);</code>


{
<code class="mwt-code" >}, 1000);</code>


titel: 'Gibt es die Matrix wirklich?',
<code class="mwt-code" >});</code>


abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',
<code class="mwt-code" >}</code>


inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'
<code class="mwt-code" >// Nutzung des Promises</code>


}
<code class="mwt-code" >fetchPublikationen().then(publikationen =</code>&gt;<code class="mwt-code" > {</code>


]
<code class="mwt-code" >console.log('Publikationen erhalten:', publikationen);</code>


},
<code class="mwt-code" >}).catch(error =</code>&gt;<code class="mwt-code" > {</code>


mutations: {
<code class="mwt-code" >console.error('Fehler beim Abrufen der Publikationen:', error);</code>


addPublikation(state, publikationen) {
<code class="mwt-code" >});</code>


state.publikationen.push(publikationen);
In diesem Beispiel simulieren wir die asynchrone Abrufoperation mit setTimeout. Die Funktion fetchPublikationen gibt ein Promise zurück, das nach einer Verzögerung von 1 Sekunde die Publikationen auflöst (resolve). Wenn ein Fehler auftritt, wird die Funktion reject aufgerufen.


}
<span id="asyncawait"></span>
== async/await ==


},
'''async/await''' ist eine syntaktische Vereinfachung für die Arbeit mit Promises, die es ermöglicht, asynchrone Operationen wie synchronen Code zu schreiben.


actions: {
Wir können das gleiche Beispiel mit async/await umsetzen:


addPublikation({ commit }, publikationen) {
'''JavaScript Code:'''


commit('addPublikation', publikationen);
<code class="mwt-code" >// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)</code>


}
<code class="mwt-code" >function fetchPublikationen() {</code>


}
<code class="mwt-code" >return new Promise((resolve, reject) =</code>&gt;<code class="mwt-code" > {</code>


});
<code class="mwt-code" >setTimeout(() =</code>&gt;<code class="mwt-code" > {</code>


'''In''' App.vue''':'''
<code class="mwt-code" >const publikationen = [</code>


&lt;template&gt;
<code class="mwt-code" >{</code>


&lt;div id=&quot;app&quot;&gt;
<code class="mwt-code" >titel: 'Gibt es die Matrix wirklich?',</code>


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
<code class="mwt-code" >abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',</code>


&lt;Publikation
<code class="mwt-code" >inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'</code>


v-for=&quot;(publikation, index) in $store.state.publikationen&quot;
<code class="mwt-code" >}</code>


:key=&quot;index&quot;
<code class="mwt-code" >];</code>


:titel=&quot;publikation.titel&quot;
<code class="mwt-code" >resolve(publikationen);</code>


:abstract=&quot;publikation.abstract&quot;
<code class="mwt-code" >}, 1000);</code>


:inhalt=&quot;publikation.inhalt&quot;
<code class="mwt-code" >});</code>


/&gt;
<code class="mwt-code" >}</code>


&lt;KommentarFormular /&gt;
<code class="mwt-code" >// Async-Funktion zum Abrufen und Anzeigen von Publikationen</code>


&lt;/div&gt;
<code class="mwt-code" >async function showPublikationen() {</code>


&lt;/template&gt;
<code class="mwt-code" >try {</code>


Mit diesen Konzepten kann man strukturierte Vue.js-Anwendung erstellen, die eine Publikation anzeigt und ein Kommentarformular enthält.
<code class="mwt-code" >const publikationen = await fetchPublikationen();</code>


<span id="mein-erstes-vue.js-projekt-in-vscode"></span>
<code class="mwt-code" >console.log('Publikationen erhalten:', publikationen);</code>
=== Mein erstes Vue.js Projekt in VSCode ===


Es beginnt wieder damit sicherzustellen, dass Node.js auf deinem System installiert ist. Falls nicht, lade es von der [https://nodejs.org/ Node.js-Website] herunter und installiere es.
<code class="mwt-code" >} catch (error) {</code>


Installiere Vue CLI global, um ein neues Vue-Projekt zu erstellen:
<code class="mwt-code" >console.error('Fehler beim Abrufen der Publikationen:', error);</code>


npm install -g @vue/cli
<code class="mwt-code" >}</code>


<span id="erstelle-ein-neues-vue-projekt"></span>
<code class="mwt-code" >}</code>
==== Erstelle ein neues Vue-Projekt ====


Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll. Führe den folgenden Befehl aus:
<code class="mwt-code" >// Aufruf der async-Funktion</code>


vue create from-peer-review-to-crowd-review
showPublikationen();


Wähle die Standardkonfiguration oder passe sie nach Bedarf an.
Dieses Beispiel erläutert:


<span id="öffne-das-projekt-in-visual-studio-code-1"></span>
* fetchPublikationen bleibt unverändert und gibt ein Promise zurück
==== Öffne das Projekt in Visual Studio Code ====
* showPublikationen ist eine async&nbsp;Funktion. Innerhalb dieser Funktion verwenden wir await, um auf das Ergebnis von fetchPublikationen zu warten. Await pausiert die Ausführung der Funktion, bis das Promise aufgelöst wird.
* Fehler werden mit try/catch behandelt, was den Code sauber und verständlich macht
Daten zwischen dem Backend und dem Frontend können in mehreren Formaten gesendet werden, meistens wird entweder XML oder JSON verwendet. XML (eXtensible Markup Language) ist ein markiertes Datenformat, das Daten in einer hierarchischen Struktur mit benutzerdefinierten Tags darstellt. Es ist sehr flexibel und kann komplexe Datenstrukturen repräsentieren, wird jedoch als schwerfälliger und aufwändiger in der Verarbeitung angesehen. JSON (JavaScript Object Notation) ist ein leichteres Format, das Daten in einer einfacheren Schlüssel-Wert-Paar-Struktur organisiert. JSON ist leichter lesbar und einfacher zu verarbeiten, insbesondere in JavaScript-Umgebungen. In der Praxis wird JSON häufiger verwendet als XML, da es einfacher zu integrieren und effizienter in modernen Webanwendungen ist. JSON lässt sich nahtlos mit JavaScript kombinieren und ermöglicht eine schnellere und unkompliziertere Datenverarbeitung.


Starte Visual Studio Code und öffne das neu erstellte Projektverzeichnis:
AJAX (Asynchronous JavaScript and XML) ermöglicht die asynchrone Kommunikation zwischen dem Browser und dem Server, wodurch Inhalte dynamisch aktualisiert werden können, ohne die ganze Seite neu zu laden. In unserem Beispiel für eine Plattform zur Veröffentlichung wissenschaftlicher Publikationen können wir AJAX verwenden, um Publikationen vom Server abzurufen und auf der Webseite anzuzeigen. Obwohl der Name &quot;AJAX&quot; XML impliziert, wird in der Praxis oft JSON verwendet.


code from-peer-review-to-crowd-review
Beispiel einer XML-Datei:


<span id="erstelle-komponenten"></span>
&lt;<code class="mwt-code" >publikation</code>&gt;
==== 4. Erstelle Komponenten ====


Erstelle eine neue Datei für die Publikation-Komponente:
&lt;<code class="mwt-code" >titel</code>&gt;<code class="mwt-code" > Die Matrix: Leben wir in einer Simulation?</code>&lt;<code class="mwt-code" >/titel</code>&gt;


* Erstelle einen neuen Ordner components im src-Verzeichnis
&lt;<code class="mwt-code" >autor</code>&gt;<code class="mwt-code" >Alice</code>&lt;<code class="mwt-code" >/autor</code>&gt;
* Füge eine Datei Publikation.vue im src/components-Ordner hinzu


'''Datei''' src/components/Publikation.vue''':'''
&lt;<code class="mwt-code" >jahr</code>&gt;<code class="mwt-code" >2024</code>&lt;<code class="mwt-code" >/jahr</code>&gt;


&lt;template&gt;
&lt;<code class="mwt-code" >/publikation</code>&gt;


&lt;div&gt;
<code class="mwt-code" >Und hier dieselbe Information als JSON-Datei:</code>


&lt;h2&gt;{{ titel }}&lt;/h2&gt;
<code class="mwt-code" >{</code>


&lt;p&gt;{{ abstract }}&lt;/p&gt;
&quot;<code class="mwt-code" >titel</code>&quot;<code class="mwt-code" >:</code>&quot;<code class="mwt-code" >Die Matrix: Leben wir in einer Simulation?</code>&quot;<code class="mwt-code" >,</code>


&lt;div&gt;{{ inhalt }}&lt;/div&gt;
&quot;<code class="mwt-code" >autor</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Alice</code>&quot;<code class="mwt-code" >,</code>


&lt;/div&gt;
&quot;<code class="mwt-code" >jahr</code>&quot;<code class="mwt-code" >: 2024</code>


&lt;/template&gt;
<code class="mwt-code" >}</code>


&lt;script&gt;
Senden wir nun eine Anfrage mit der fetch-API. Der Server liefert die Publikationen im JSON-Format zurück. Diese Daten werden dann verarbeitet und in der Benutzeroberfläche angezeigt, ohne dass die Seite neu geladen wird.


export default {
<code class="mwt-code" >async function fetchPublikationen() {</code>


props: {
<code class="mwt-code" >try {</code>


titel: String,
<code class="mwt-code" >const response = await fetch('https://api.example.com/publikationen');</code>


abstract: String,
<code class="mwt-code" >if (!response.ok) {</code>


inhalt: String
<code class="mwt-code" >throw new Error('Netzwerkantwort war nicht okay.');</code>


}
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >const data = await response.json();</code>


&lt;/script&gt;
<code class="mwt-code" >console.log('Publikationen erhalten:', data);</code>


&lt;style scoped&gt;
<code class="mwt-code" >displayPublikationen(data);</code>


/* Styles für die Publikation */
<code class="mwt-code" >} catch (error) {</code>


&lt;/style&gt;
<code class="mwt-code" >console.error('Fehler beim Abrufen der Publikationen:', error);</code>


Füge eine Datei KommentarFormular.vue im src/components-Ordner hinzu.
<code class="mwt-code" >}</code>


'''Datei''' src/components/KommentarFormular.vue''':'''
<code class="mwt-code" >}</code>


&lt;template&gt;
<code class="mwt-code" >function displayPublikationen(publikationen) {</code>


&lt;form @submit.prevent=&quot;onSubmit&quot;&gt;
<code class="mwt-code" >const container = document.getElementById('publikationen-container');</code>


&lt;textarea v-model=&quot;kommentar&quot; placeholder=&quot;Fügen Sie einen Kommentar hinzu...&quot; required&gt;&lt;/textarea&gt;
<code class="mwt-code" >container.innerHTML = publikationen.map(p =</code>&gt;<code class="mwt-code" > `</code>


&lt;button type=&quot;submit&quot;&gt;Kommentar hinzufügen&lt;/button&gt;
&lt;<code class="mwt-code" >div</code>&gt;


&lt;/form&gt;
&lt;<code class="mwt-code" >h2</code>&gt;<code class="mwt-code" >${p.titel}</code>&lt;<code class="mwt-code" >/h2</code>&gt;


&lt;/template&gt;
&lt;<code class="mwt-code" >p</code>&gt;<code class="mwt-code" >${p.autor}</code>&lt;<code class="mwt-code" >/p</code>&gt;


&lt;script&gt;
&lt;<code class="mwt-code" >div</code>&gt;<code class="mwt-code" >${p.jahr}</code>&lt;<code class="mwt-code" >/div</code>&gt;


export default {
&lt;<code class="mwt-code" >/div</code>&gt;


data() {
<code class="mwt-code" >`).join('');</code>


return {
<code class="mwt-code" >}</code>


kommentar: ''
fetchPublikationen();


}
In diesem Code wird eine Anfrage an die API gesendet, um Publikationen zu erhalten. Die JSON-Daten werden dann verarbeitet und die Inhalte auf der Webseite angezeigt, was eine dynamische und reaktive Benutzererfahrung ermöglicht. Es ist üblich Beispiel-Serverantworten und -anfragen lokal zu speichern und diese Daten (üblicherweise in der Praxis oft JSON-Dateien) im Frontend zu verwenden, also die Daten anhand von diesen JSON Dateien anzuzeigen.


},
<span id="api-definitionen"></span>
== API Definitionen ==


methods: {
API-Definitionen sind von zentraler Bedeutung für die Erstellung klarer und konsistenter Schnittstellen, die den Datenaustausch zwischen verschiedenen Systemen regeln. Sie bieten eine strukturierte Übersicht über verfügbare Endpunkte, erforderliche Parameter und die Formate der zurückgegebenen Daten, was die Integration von Frontend und Backend vereinfacht. OpenAPI (The Linux Foundation, 2024)''',''' ehemals bekannt als Swagger, ist ein weit verbreitetes Tool zur Definition und Dokumentation von APIs. Mit OpenAPI können Entwickler präzise API-Spezifikationen in einem maschinenlesbaren Format erstellen, das auch interaktive Dokumentation umfasst. Diese Dokumentation erleichtert es Entwicklern, die API zu verstehen und zu testen, ohne direkt mit dem Backend-Code interagieren zu müssen. OpenAPI unterstützt die klare Kommunikation der API-Funktionalitäten und trägt zur Konsistenz und Interoperabilität bei der Systemintegration bei.


onSubmit() {
Um die OpenAPI-Spezifikation für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen visuell anzusehen und zu testen, können wir die Swagger UI verwenden. Hier ist eine Schritt-für-Schritt-Anleitung, wie dies aussehen kann:


alert('Kommentar hinzugefügt: ' + this.kommentar);
<span id="swagger-ui-verwenden"></span>
=== Swagger UI verwenden ===


this.kommentar = '';
'''Swagger UI lokal einrichten''':


}
* Lade die [https://github.com/swagger-api/swagger-ui Swagger UI] herunter oder klone das Repository
* Öffne das Verzeichnis dist und kopiere die Dateien swagger-ui-bundle.js, swagger-ui-standalone-preset.js und&nbsp;swagger-ui.css in ein Verzeichnis, das von deinem Webserver bereitgestellt wird
'''OpenAPI-Spezifikation einbinden''':


}
Erstelle eine HTML-Datei, zum Beispiel index.html, im selben Verzeichnis wie die Swagger UI Dateien und binde die OpenAPI-Spezifikation ein. Die index.html könnte folgendermaßen aussehen:
&lt;<code class="mwt-code">!DOCTYPE html</code>&gt;
&lt;<code class="mwt-code">html lang=</code>"<code class="mwt-code">en</code>"&gt;
&lt;<code class="mwt-code">head</code>&gt;
&lt;<code class="mwt-code">meta charset=</code>"<code class="mwt-code">UTF-8</code>"&gt;
&lt;<code class="mwt-code">title</code>&gt;<code class="mwt-code">Swagger UI</code>&lt;<code class="mwt-code">/title</code>&gt;


}
&lt;<code class="mwt-code">link rel=</code>"<code class="mwt-code">stylesheet</code>"<code class="mwt-code"> type=</code>"<code class="mwt-code">text/css</code>"<code class="mwt-code"> href=</code>"<code class="mwt-code">swagger-ui.css</code>"<code class="mwt-code"> </code>&gt;


&lt;/script&gt;
&lt;<code class="mwt-code">script src=</code>"<code class="mwt-code">swagger-ui-bundle.js</code>"<code class="mwt-code"> charset=</code>"<code class="mwt-code">UTF-8</code>"&gt;<code class="mwt-code"> </code>&lt;<code class="mwt-code">/script</code>&gt;
&lt;<code class="mwt-code">script src=</code>"<code class="mwt-code">swagger-ui-standalone-preset.js</code>"<code class="mwt-code"> charset=</code>"<code class="mwt-code">UTF-8</code>"&gt;<code class="mwt-code"> </code>&lt;<code class="mwt-code">/script</code>&gt;


&lt;style scoped&gt;
&lt;<code class="mwt-code">script</code>&gt;
<code class="mwt-code">  window.onload = function() {</code>
<code class="mwt-code">  const ui = SwaggerUIBundle({</code>
<code class="mwt-code">  url: </code>"<code class="mwt-code">path/to/your/openapi.yaml</code>"<code class="mwt-code">, // Pfad zu deiner OpenAPI-Spezifikation</code>
<code class="mwt-code">  dom_id: '#swagger-ui',</code>
<code class="mwt-code">  presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],</code>
<code class="mwt-code">  layout: </code>"<code class="mwt-code">StandaloneLayout</code>"
<code class="mwt-code">  });</code>


/* Styles für das Kommentarformular */
<code class="mwt-code">  window.ui = ui;</code>


&lt;/style&gt;
<code class="mwt-code">}</code>


<span id="konfiguriere-routing"></span>
&lt;<code class="mwt-code">/script</code>&gt;
==== Konfiguriere Routing ====
&lt;<code class="mwt-code">/head</code>&gt;
&lt;<code class="mwt-code">body</code>&gt;
&lt;<code class="mwt-code">div id=</code>"<code class="mwt-code">swagger-ui</code>"&gt;&lt;<code class="mwt-code">/div</code>&gt;
&lt;<code class="mwt-code">/body</code>&gt;
&lt;<code class="mwt-code">/html</code>&gt;


Falls das Projekt noch keinen Router enthält, installiere Vue Router:


npm install vue-router
Ersetze path/to/your/openapi.yaml durch den Pfad zu deiner OpenAPI-Spezifikation.


Erstelle eine Datei router/index.js im src-Verzeichnis:
'''Swagger UI lokal öffnen''':


'''Datei''' src/router/index.js''':'''
Starte einen lokalen Webserver, um die index.html Datei anzuzeigen. Zum Beispiel kannst man dies mit Python tun: python -m http.server im Verzeichnis mit der index.html Datei.


import Vue from 'vue';
Öffne deinen Browser und navigiere zu der URL, die deinem lokalen Webserver zugewiesen ist, wie http://localhost:8000, um die interaktive API-Dokumentation deiner Publikationen-Plattform zu sehen.


import Router from 'vue-router';
<span id="api-definition-für-unser-fallbeispiel"></span>


import Publikation from '../components/Publikation.vue';
=== API Definition für unser Fallbeispiel ===


import KommentarFormular from '../components/KommentarFormular.vue';
In unserem Beispiel könnte man sich folgende vereinfachte API Definitionen vorstellen:


Vue.use(Router);
<code class="mwt-code" >POST /register</code>


export default new Router({
<code class="mwt-code" >POST /login</code>


routes: [
<code class="mwt-code" >POST /publications</code>


{
<code class="mwt-code" >GET /publications/{id}</code>


path: '/publikationen',
<code class="mwt-code" >POST /reviews</code>


name: 'Publikation',
<code class="mwt-code" >GET /comments?publicationId={id}</code>


component: Publikation
POST erstellt neue Daten auf dem Server. PUT aktualisiert bestehende Daten. GET ruft Daten vom Server ab, ohne sie zu ändern. Im Frontend Development ist sollte man immer die gesamte Applikation verstehen und wie die Daten am effizientesten zwischen dem Server und dem Frontend ausgetauscht werden können. Deshalb ist es wichtig sich die API-Definition, sowie das UI-Design, am Anfang eines neuen Frontendprojekts gut zu überlegen. Die API-Definition ist der Vertrag zwischen der UI und dem Server. Sehen wir uns nun die Datenübertragung für ein paar Endpunkte im Detail an.


},
# POST /register
'''Beschreibung:''' Registriert einen neuen Benutzer im System.


{
<blockquote>'''Anfrage:'''


path: '/',
<code class="mwt-code" >{</code>


name: 'KommentarFormular',
&quot;<code class="mwt-code" >username</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >alice</code>&quot;<code class="mwt-code" >,</code>


component: KommentarFormular
&quot;<code class="mwt-code" >email</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >alice@example.com</code>&quot;<code class="mwt-code" >,</code>


}
&quot;<code class="mwt-code" >password</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >securepassword</code>&quot;<code class="mwt-code" >,</code>


]
&quot;<code class="mwt-code" >role</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Author</code>&quot;


});
<code class="mwt-code" >}</code>


<span id="verwende-die-komponenten-in-app.vue"></span>
'''Antwort:'''
==== Verwende die Komponenten in App.vue ====


Ersetze den Inhalt der App.vue, um die Publikation- und KommentarFormular-Komponenten einzuschließen:
<code class="mwt-code" >{</code>


'''Datei''' src/App.vue''':'''
&quot;<code class="mwt-code" >id</code>&quot;<code class="mwt-code" >: 1,</code>


&lt;template&gt;
&quot;<code class="mwt-code" >username</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >alice</code>&quot;<code class="mwt-code" >,</code>


&lt;div id=&quot;app&quot;&gt;
&quot;<code class="mwt-code" >email</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >alice@example.com</code>&quot;<code class="mwt-code" >,</code>


&lt;h1&gt;Wissenschaftliche Publikationen&lt;/h1&gt;
&quot;<code class="mwt-code" >role</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Author</code>&quot;


&lt;Publikation
<code class="mwt-code" >}</code></blockquote>
<ol style="list-style-type: decimal;" start="2">
<li><p>POST /login</p></li>
</ol>
<blockquote>'''Beschreibung:''' Authentifiziert einen Benutzer und erstellt eine Sitzung.


v-for=&quot;(publikation, index) in publikationen&quot;
'''Anfrage:'''


:key=&quot;index&quot;
<code class="mwt-code" >{</code>


:titel=&quot;publikation.titel&quot;
&quot;<code class="mwt-code" >email</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >alice@example.com</code>&quot;<code class="mwt-code" >,</code>


:abstract=&quot;publikation.abstract&quot;
&quot;<code class="mwt-code" >password</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >securepassword</code>&quot;


:inhalt=&quot;publikation.inhalt&quot;
<code class="mwt-code" >}</code>


/&gt;
'''Antwort:'''


&lt;KommentarFormular /&gt;
<code class="mwt-code" >{</code>


&lt;/div&gt;
&quot;<code class="mwt-code" >token</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >jwt-token-string</code>&quot;


&lt;/template&gt;
<code class="mwt-code" >}</code></blockquote>
<ol style="list-style-type: decimal;" start="3">
<li><p>POST /publications</p></li>
</ol>
'''Beschreibung:'''Erstellt eine neue wissenschaftliche Publikation.


&lt;script&gt;
'''Anfrage:'''


import Publikation from './components/Publikation.vue';
<code class="mwt-code" >{</code>


import KommentarFormular from './components/KommentarFormular.vue';
&quot;<code class="mwt-code" >title</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Einfluss von KI auf Peer-Review-Prozesse</code>&quot;<code class="mwt-code" >,</code>


export default {
&quot;<code class="mwt-code" >abstract</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Diese Arbeit untersucht...</code>&quot;<code class="mwt-code" >,</code>


components: {
&quot;<code class="mwt-code" >content</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Der komplette Inhalt...</code>&quot;<code class="mwt-code" >,</code>


Publikation,
&quot;<code class="mwt-code" >authorId</code>&quot;<code class="mwt-code" >: 1</code>


KommentarFormular
<code class="mwt-code" >}</code>


},
'''Antwort:'''


data() {
<code class="mwt-code" >{</code>


return {
&quot;<code class="mwt-code" >id</code>&quot;<code class="mwt-code" >: 101,</code>


publikationen: [
&quot;<code class="mwt-code" >title</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Einfluss von KI auf Peer-Review-Prozesse</code>&quot;<code class="mwt-code" >,</code>


{
&quot;<code class="mwt-code" >status</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Eingereicht</code>&quot;


titel: 'Gibt es die Matrix wirklich?',
<code class="mwt-code" >}</code>


abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',
<ol style="list-style-type: decimal;" start="4">
<li><p>GET /publications/{id}</p></li>
</ol>
<blockquote>'''Beschreibung:''' Gibt Details zu einer spezifischen Publikation zurück.


inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'
'''Parameter:'''</blockquote>
* id (Pfadparameter): Die ID der Publikation.
<blockquote>'''Antwort:'''


}
{


]
&quot;id&quot;: 101,


}
&quot;title&quot;: &quot;Einfluss von KI auf Peer-Review-Prozesse&quot;,


}
&quot;abstract&quot;: &quot;Diese Arbeit untersucht...&quot;,


}
&quot;content&quot;: &quot;Der komplette Inhalt...&quot;,


&lt;/script&gt;
&quot;status&quot;: &quot;Eingereicht&quot;,


&lt;style&gt;
&quot;authorId&quot;: 1


/* Styles für die App */
}</blockquote>
<ol style="list-style-type: decimal;" start="5">
<li><p>POST /reviews</p></li>
</ol>
<blockquote>'''Beschreibung:''' Ein Gutachter erstellt ein Gutachten für eine Publikation.


&lt;/style&gt;
'''Anfrage:'''


<span id="starte-die-anwendung-1"></span>
{
==== Starte die Anwendung ====


Starte den Vue-Entwicklungsserver, um die Anwendung auszuführen:
&quot;publicationId&quot;: 101,


npm run serve
&quot;reviewerId&quot;: 2,


Öffne einen Webbrowser und gehe zu http://localhost:8080, um die Anwendung zu sehen.
&quot;comments&quot;: &quot;Die Arbeit ist gut, aber...&quot;,


Jetzt haben wir ein funktionierendes Vue.js-Projekt erstellt, welches eine Publikation anzeigt und ein Kommentarformular enthält.
&quot;recommendation&quot;: &quot;Kleine Überarbeitung&quot;


<span id="asynchrone-programmierung-und-datenübertragung"></span>
}
= Asynchrone Programmierung und Datenübertragung =


Frontend-Entwicklung konzentriert sich auf die Gestaltung der Benutzeroberfläche und Interaktivität einer Webanwendung unter Verwendung moderner Technologien wie HTML5, CSS3 und JavaScript-Frameworks wie React, Angular oder Vue.js. Im Full-Stack-Kontext arbeitet das Frontend mit dem Backend zusammen, das durch Technologien wie Node.js, Express und Datenbanken wie MongoDB oder PostgreSQL unterstützt wird. Die Kommunikation zwischen Frontend und Backend erfolgt typischerweise durch RESTful APIs oder GraphQL, wobei JSON oder XML als Formate für den Datenaustausch verwendet werden. Promises und async/await sind Methoden zur Handhabung von asynchronem Code in JavaScript. Sie helfen dabei, Code lesbarer und wartbarer zu machen, insbesondere wenn man mit asynchronen Operationen wie API-Anfragen oder Datenverarbeitung arbeitet.
'''Antwort:'''


Sehen wir uns nun an, wie man Promises und async/await in unserem Beispiel anwenden kann. Promises sind Objekte, die einen zukünftigen Wert repräsentieren. Sie bieten eine Möglichkeit, asynchrone Operationen zu verwalten, indem sie auf den Abschluss dieser Operation warten.
<code class="mwt-code" >{</code>


Angenommen, wir möchten die Publikationen von einem Server abrufen. Wir verwenden eine Funktion, die ein Promise zurückgibt:
&quot;<code class="mwt-code" >id</code>&quot;<code class="mwt-code" >: 201,</code>


'''JavaScript Code:'''
&quot;<code class="mwt-code" >publicationId</code>&quot;<code class="mwt-code" >: 101,</code>


// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)
&quot;<code class="mwt-code" >reviewerId</code>&quot;<code class="mwt-code" >: 2,</code>


function fetchPublikationen() {
&quot;<code class="mwt-code" >status</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Gutachten erstellt</code>&quot;


return new Promise((resolve, reject) =&gt; {
<code class="mwt-code" >}</code></blockquote>
<ol style="list-style-type: decimal;" start="6">
<li><p>GET /comments?publicationId={id}</p></li>
</ol>
<blockquote>'''Beschreibung:''' Listet alle Kommentare zu einer Publikation auf.


setTimeout(() =&gt; {
'''Parameter:'''</blockquote>
* publicationId (Query-Parameter): Die ID der Publikation.
<blockquote>'''Antwort:'''


const publikationen = [
<code class="mwt-code" >[</code>


{
<code class="mwt-code" >{</code>


titel: 'Gibt es die Matrix wirklich?',
&quot;<code class="mwt-code" >id</code>&quot;<code class="mwt-code" >: 301,</code>


abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',
&quot;<code class="mwt-code" >publicationId</code>&quot;<code class="mwt-code" >: 101,</code>


inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'
&quot;<code class="mwt-code" >userId</code>&quot;<code class="mwt-code" >: 3,</code>


}
&quot;<code class="mwt-code" >content</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Sehr interessante Ergebnisse!</code>&quot;


];
<code class="mwt-code" >},</code>


resolve(publikationen);
<code class="mwt-code" >{</code>


}, 1000);
&quot;<code class="mwt-code" >id</code>&quot;<code class="mwt-code" >: 302,</code>


});
&quot;<code class="mwt-code" >publicationId</code>&quot;<code class="mwt-code" >: 101,</code>


}
&quot;<code class="mwt-code" >userId</code>&quot;<code class="mwt-code" >: 4,</code>


// Nutzung des Promises
&quot;<code class="mwt-code" >content</code>&quot;<code class="mwt-code" >: </code>&quot;<code class="mwt-code" >Ich stimme dem Gutachter zu, aber...</code>&quot;


fetchPublikationen().then(publikationen =&gt; {
<code class="mwt-code" >}</code>


console.log('Publikationen erhalten:', publikationen);
<code class="mwt-code" >]</code></blockquote>


}).catch(error =&gt; {
<span id="alternative-tools"></span>
=== Alternative Tools ===


console.error('Fehler beim Abrufen der Publikationen:', error);
Es gibt auch online Tools zur API-Dokumentation. Beispielsweise:


});
* Swagger Editor (SmartBear, 2024): Besuche Swagger Editor, lade eine OpenAPI-Spezifikation hoch oder füge den Inhalt direkt ein, um die API-Dokumentation zu erstellen und zu testen.
* Postman (Postman, Inc., 2024): Lade eine OpenAPI-Spezifikation in Postman, um die API-Dokumentation anzuzeigen und API-Anfragen zu testen.
Diese Tools helfen, die API-Dokumentation für die Plattform zu visualisieren und zu überprüfen, wie die API funktioniert.


In diesem Beispiel simulieren wir die asynchrone Abrufoperation mit setTimeout. Die Funktion fetchPublikationen gibt ein Promise zurück, das nach einer Verzögerung von 1 Sekunde die Publikationen auflöst (resolve). Wenn ein Fehler auftritt, wird die Funktion reject aufgerufen.
<span id="responsive-webdesign"></span>
= Responsive Webdesign =


<span id="asyncawait"></span>
Responsive Webdesign sorgt dafür, dass Websites auf allen Geräten gut aussehen, indem sie sich automatisch an verschiedene Bildschirmgrößen anpassen. Zu den Prinzipien gehören flexible Layouts, die sich an unterschiedliche Bildschirmgrößen anpassen, skalierbare Bilder und Schriften sowie die Verwendung von Media Queries in CSS, um spezifische Stile für verschiedene Geräte zu definieren. Ziel ist es, eine konsistente und nutzerfreundliche Erfahrung auf Smartphones, Tablets und Desktops zu bieten.
== async/await ==


'''async/await''' ist eine syntaktische Vereinfachung für die Arbeit mit Promises, die es ermöglicht, asynchrone Operationen wie synchronen Code zu schreiben.
<span id="gestaltung-von-benutzeroberflächen-die-auf-verschiedenen-geräten-und-bildschirmgrößen-gut-funktionieren"></span>
== Gestaltung von Benutzeroberflächen, die auf verschiedenen Geräten und Bildschirmgrößen gut funktionieren ==


Wir können das gleiche Beispiel mit async/await umsetzen:
Sehen wir uns ein paar HTML und CSS-Konzepte an, die es ermöglichen Elemente unterschiedlich auf unterschiedlichen Geräten darzustellen. Die besprochenen JavaScript Frameworks helfen auch dabei Websites zu designen die sowohl auf großen Bildschirmen als auch auf Smartphones gut bedienbar sind.


'''JavaScript Code:'''
<span id="responsive-layout"></span>
=== Responsive Layout ===


// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)
Verwende Flexbox für ein flexibles Layout, das sich an verschiedene Bildschirmgrößen anpasst.


function fetchPublikationen() {
&lt;<code class="mwt-code" >!-- HTML-Struktur --</code>&gt;


return new Promise((resolve, reject) =&gt; {
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >publikationen-container</code>&quot;&gt;


setTimeout(() =&gt; {
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >publikation</code>&quot;&gt;


const publikationen = [
&lt;<code class="mwt-code" >h2</code>&gt;<code class="mwt-code" >Publikation 1</code>&lt;<code class="mwt-code" >/h2</code>&gt;


{
&lt;<code class="mwt-code" >p</code>&gt;<code class="mwt-code" >Abstract...</code>&lt;<code class="mwt-code" >/p</code>&gt;


titel: 'Gibt es die Matrix wirklich?',
&lt;<code class="mwt-code" >/div</code>&gt;


abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >publikation</code>&quot;&gt;


inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'
&lt;<code class="mwt-code" >h2</code>&gt;<code class="mwt-code" >Publikation 2</code>&lt;<code class="mwt-code" >/h2</code>&gt;


}
&lt;<code class="mwt-code" >p</code>&gt;<code class="mwt-code" >Abstract...</code>&lt;<code class="mwt-code" >/p</code>&gt;


];
&lt;<code class="mwt-code" >/div</code>&gt;


resolve(publikationen);
&lt;<code class="mwt-code" >!-- Weitere Publikationen --</code>&gt;


}, 1000);
&lt;<code class="mwt-code" >/div</code>&gt;


});
<code class="mwt-code" >/* CSS für responsives Layout */</code>


}
<code class="mwt-code" >.publikationen-container {</code>


// Async-Funktion zum Abrufen und Anzeigen von Publikationen
<code class="mwt-code" >display: flex;</code>


async function showPublikationen() {
<code class="mwt-code" >flex-wrap: wrap;</code>


try {
<code class="mwt-code" >gap: 16px;</code>


const publikationen = await fetchPublikationen();
<code class="mwt-code" >}</code>


console.log('Publikationen erhalten:', publikationen);
<code class="mwt-code" >.publikation {</code>


} catch (error) {
<code class="mwt-code" >flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout mit Abstand */</code>


console.error('Fehler beim Abrufen der Publikationen:', error);
<code class="mwt-code" >box-sizing: border-box;</code>


}
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >@media (max-width: 768px) {</code>


// Aufruf der async-Funktion
<code class="mwt-code" >.publikation {</code>


showPublikationen();
<code class="mwt-code" >flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout auf Tablets */</code>


Dieses Beispiel erläutert:
<code class="mwt-code" >}</code>


* fetchPublikationen bleibt unverändert und gibt ein Promise zurück
<code class="mwt-code" >}</code>
* showPublikationen ist eine async Funktion. Innerhalb dieser Funktion verwenden wir await, um auf das Ergebnis von fetchPublikationen zu warten. Await pausiert die Ausführung der Funktion, bis das Promise aufgelöst wird.
* Fehler werden mit try/catch behandelt, was den Code sauber und verständlich macht


Daten zwischen dem Backend und dem Frontend können in mehreren Formaten gesendet werden, meistens wird entweder XML oder JSON verwendet. XML (eXtensible Markup Language) ist ein markiertes Datenformat, das Daten in einer hierarchischen Struktur mit benutzerdefinierten Tags darstellt. Es ist sehr flexibel und kann komplexe Datenstrukturen repräsentieren, wird jedoch als schwerfälliger und aufwändiger in der Verarbeitung angesehen. JSON (JavaScript Object Notation) ist ein leichteres Format, das Daten in einer einfacheren Schlüssel-Wert-Paar-Struktur organisiert. JSON ist leichter lesbar und einfacher zu verarbeiten, insbesondere in JavaScript-Umgebungen. In der Praxis wird JSON häufiger verwendet als XML, da es einfacher zu integrieren und effizienter in modernen Webanwendungen ist. JSON lässt sich nahtlos mit JavaScript kombinieren und ermöglicht eine schnellere und unkompliziertere Datenverarbeitung.
<code class="mwt-code" >@media (max-width: 480px) {</code>


AJAX (Asynchronous JavaScript and XML) ermöglicht die asynchrone Kommunikation zwischen dem Browser und dem Server, wodurch Inhalte dynamisch aktualisiert werden können, ohne die ganze Seite neu zu laden. In unserem Beispiel für eine Plattform zur Veröffentlichung wissenschaftlicher Publikationen können wir AJAX verwenden, um Publikationen vom Server abzurufen und auf der Webseite anzuzeigen. Obwohl der Name &quot;AJAX&quot; XML impliziert, wird in der Praxis oft JSON verwendet.
<code class="mwt-code" >.publikation {</code>


Beispiel einer XML-Datei:
<code class="mwt-code" >flex: 1 1 100%; /* Einspaltiges Layout auf Mobilgeräten */</code>


&lt;publikation&gt;
<code class="mwt-code" >}</code>


&lt;titel&gt; Die Matrix: Leben wir in einer Simulation?&lt;/titel&gt;
<code class="mwt-code" >}</code>


&lt;autor&gt;Alice&lt;/autor&gt;
<span id="media-queries"></span>
=== Media Queries ===


&lt;jahr&gt;2024&lt;/jahr&gt;
Passe Stile für unterschiedliche Bildschirmgrößen an, um das Layout und die Schriftgröße zu optimieren.


&lt;/publikation&gt;
<code class="mwt-code" >/* Media Queries für unterschiedliche Bildschirmgrößen */</code>


Und hier dieselbe Information als JSON-Datei:
<code class="mwt-code" >@media (max-width: 1200px) {</code>


{
<code class="mwt-code" >.header {</code>


&quot;titel&quot;:&quot;Die Matrix: Leben wir in einer Simulation?&quot;,
<code class="mwt-code" >font-size: 1.5em;</code>


&quot;autor&quot;: &quot;Alice&quot;,
<code class="mwt-code" >}</code>


&quot;jahr&quot;: 2024
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >@media (max-width: 768px) {</code>


Senden wir nun eine Anfrage mit der fetch-API. Der Server liefert die Publikationen im JSON-Format zurück. Diese Daten werden dann verarbeitet und in der Benutzeroberfläche angezeigt, ohne dass die Seite neu geladen wird.
<code class="mwt-code" >.header {</code>


async function fetchPublikationen() {
<code class="mwt-code" >font-size: 1.2em;</code>


try {
<code class="mwt-code" >}</code>


const response = await fetch('https://api.example.com/publikationen');
<code class="mwt-code" >.navigation {</code>


if (!response.ok) {
<code class="mwt-code" >display: none; /* Navigation auf kleineren Bildschirmen ausblenden */</code>


throw new Error('Netzwerkantwort war nicht okay.');
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >}</code>


const data = await response.json();
<span id="flexible-bilder"></span>
=== Flexible Bilder ===


console.log('Publikationen erhalten:', data);
Stelle sicher, dass Bilder sich proportional zur Bildschirmgröße skalieren.


displayPublikationen(data);
<code class="mwt-code" >/* Flexibles Bild */</code>


} catch (error) {
<code class="mwt-code" >img {</code>


console.error('Fehler beim Abrufen der Publikationen:', error);
<code class="mwt-code" >max-width: 100%;</code>


}
<code class="mwt-code" >height: auto;</code>


}
<code class="mwt-code" >}</code>


function displayPublikationen(publikationen) {
<span id="touchfreundliche-elemente"></span>
=== Touchfreundliche Elemente ===


const container = document.getElementById('publikationen-container');
Gestalte Schaltflächen und Links groß genug für eine einfache Bedienung auf Touchscreens.


container.innerHTML = publikationen.map(p =&gt; `
<code class="mwt-code" >/* Touchfreundliche Schaltflächen */</code>


&lt;div&gt;
<code class="mwt-code" >button {</code>


&lt;h2&gt;${p.titel}&lt;/h2&gt;
<code class="mwt-code" >padding: 12px 20px;</code>


&lt;p&gt;${p.autor}&lt;/p&gt;
<code class="mwt-code" >font-size: 16px;</code>


&lt;div&gt;${p.jahr}&lt;/div&gt;
<code class="mwt-code" >}</code>


&lt;/div&gt;
<span id="testen"></span>
=== Testen ===


`).join('');
Nutze Entwicklertools in Browsern oder echte Geräte, um das Layout und die Funktionalität auf verschiedenen Bildschirmgrößen zu überprüfen. Mit diesen Techniken und Beispielen kannst man sicherstellen, dass unsere Plattform für wissenschaftliche Publikationen auf allen Geräten gut aussieht und benutzerfreundlich ist.


}
<span id="medienabfragen-und-die-verwendung-von-css-frameworks-zur-unterstützung-des-responsiven-designs"></span>
== Medienabfragen und die Verwendung von CSS-Frameworks zur Unterstützung des responsiven Designs ==


fetchPublikationen();
<span id="medienabfragen"></span>
=== Medienabfragen ===


In diesem Code wird eine Anfrage an die API gesendet, um Publikationen zu erhalten. Die JSON-Daten werden dann verarbeitet und die Inhalte auf der Webseite angezeigt, was eine dynamische und reaktive Benutzererfahrung ermöglicht. Es ist üblich Beispiel-Serverantworten und -anfragen lokal zu speichern und diese Daten (üblicherweise in der Praxis oft JSON-Dateien) im Frontend zu verwenden, also die Daten anhand von diesen JSON Dateien anzuzeigen.
Medienabfragen ermöglichen es, CSS-Stile basierend auf den Eigenschaften des Geräts wie Bildschirmgröße und -auflösung anzupassen. Sie sind besonders nützlich, um sicherzustellen, dass deine Plattform auf verschiedenen Bildschirmgrößen gut aussieht.


<span id="api-definitionen"></span>
'''Beispiel:''' Wir möchten das Layout der Publikationen auf unterschiedlichen Geräten anpassen.
== API Definitionen ==


API-Definitionen sind von zentraler Bedeutung für die Erstellung klarer und konsistenter Schnittstellen, die den Datenaustausch zwischen verschiedenen Systemen regeln. Sie bieten eine strukturierte Übersicht über verfügbare Endpunkte, erforderliche Parameter und die Formate der zurückgegebenen Daten, was die Integration von Frontend und Backend vereinfacht. OpenAPI (The Linux Foundation, 2024)''',''' ehemals bekannt als Swagger, ist ein weit verbreitetes Tool zur Definition und Dokumentation von APIs. Mit OpenAPI können Entwickler präzise API-Spezifikationen in einem maschinenlesbaren Format erstellen, das auch interaktive Dokumentation umfasst. Diese Dokumentation erleichtert es Entwicklern, die API zu verstehen und zu testen, ohne direkt mit dem Backend-Code interagieren zu müssen. OpenAPI unterstützt die klare Kommunikation der API-Funktionalitäten und trägt zur Konsistenz und Interoperabilität bei der Systemintegration bei.
<code class="mwt-code" >/* Standardlayout für große Bildschirme */</code>


Um die OpenAPI-Spezifikation für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen visuell anzusehen und zu testen, können wir die Swagger UI verwenden. Hier ist eine Schritt-für-Schritt-Anleitung, wie dies aussehen kann:
<code class="mwt-code" >.publikationen-container {</code>


<span id="swagger-ui-verwenden"></span>
<code class="mwt-code" >display: flex;</code>
=== Swagger UI verwenden ===


'''Swagger UI lokal einrichten''':
<code class="mwt-code" >flex-wrap: wrap;</code>


* Lade die [https://github.com/swagger-api/swagger-ui Swagger UI] herunter oder klone das Repository
<code class="mwt-code" >gap: 16px;</code>
* Öffne das Verzeichnis dist und kopiere die Dateien swagger-ui-bundle.js, swagger-ui-standalone-preset.js und swagger-ui.css in ein Verzeichnis, das von deinem Webserver bereitgestellt wird


'''OpenAPI-Spezifikation einbinden''':
<code class="mwt-code" >}</code>


Erstelle eine HTML-Datei, zum Beispiel index.html, im selben Verzeichnis wie die Swagger UI Dateien und binde die OpenAPI-Spezifikation ein. Die index.html könnte folgendermaßen aussehen:
<code class="mwt-code" >.publikation {</code>


&lt;!DOCTYPE html&gt;
<code class="mwt-code" >flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout für große Bildschirme */</code>


&lt;html lang=&quot;en&quot;&gt;
<code class="mwt-code" >box-sizing: border-box;</code>


&lt;head&gt;
<code class="mwt-code" >}</code>


&lt;meta charset=&quot;UTF-8&quot;&gt;
<code class="mwt-code" >/* Layout für Tablets */</code>


&lt;title&gt;Swagger UI&lt;/title&gt;
<code class="mwt-code" >@media (max-width: 768px) {</code>


&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;swagger-ui.css&quot; &gt;
<code class="mwt-code" >.publikation {</code>


&lt;script src=&quot;swagger-ui-bundle.js&quot; charset=&quot;UTF-8&quot;&gt; &lt;/script&gt;
<code class="mwt-code" >flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout für Tablets */</code>


&lt;script src=&quot;swagger-ui-standalone-preset.js&quot; charset=&quot;UTF-8&quot;&gt; &lt;/script&gt;
<code class="mwt-code" >}</code>


&lt;script&gt;
<code class="mwt-code" >}</code>


window.onload = function() {
<code class="mwt-code" >/* Layout für Mobilgeräte */</code>


const ui = SwaggerUIBundle({
<code class="mwt-code" >@media (max-width: 480px) {</code>


url: &quot;path/to/your/openapi.yaml&quot;, // Pfad zu deiner OpenAPI-Spezifikation
<code class="mwt-code" >.publikation {</code>


dom_id: '#swagger-ui',
<code class="mwt-code" >flex: 1 1 100%; /* Einspaltiges Layout für Mobilgeräte */</code>


presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
<code class="mwt-code" >}</code>


layout: &quot;StandaloneLayout&quot;
<code class="mwt-code" >}</code>


});
<span id="verwendung-von-css-frameworks"></span>
=== Verwendung von CSS-Frameworks ===


window.ui = ui;
CSS-Frameworks bieten vorgefertigte Klassen und Komponenten, die helfen, responsives Design schnell und einfach zu implementieren. Beliebte Frameworks sind Bootstrap, Foundation und Tailwind CSS.


}
Bootstrap ist ein weit verbreitetes CSS-Framework, das eine Reihe von nützlichen Klassen für responsives Design bereitstellt. Füge die Bootstrap CSS-Datei in deinem HTML-Dokument ein.


&lt;/script&gt;
&lt;<code class="mwt-code" >!-- Bootstrap CSS einbinden --</code>&gt;


&lt;/head&gt;
&lt;<code class="mwt-code" >link rel=</code>&quot;<code class="mwt-code" >stylesheet</code>&quot;<code class="mwt-code" > href=</code>&quot;<code class="mwt-code" >https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css</code>&quot;&gt;


&lt;body&gt;
<code class="mwt-code" >Verwende Bootstrap-Klassen, um ein responsives Layout für deine Publikationen zu erstellen.</code>


&lt;div id=&quot;swagger-ui&quot;&gt;&lt;/div&gt;
&lt;<code class="mwt-code" >!-- HTML-Struktur mit Bootstrap-Klassen --</code>&gt;


&lt;/body&gt;
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >container</code>&quot;&gt;


&lt;/html&gt;
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >row</code>&quot;&gt;


Ersetze path/to/your/openapi.yaml durch den Pfad zu deiner OpenAPI-Spezifikation.
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >col-md-4 mb-4</code>&quot;&gt;


'''Swagger UI lokal öffnen''':
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >card</code>&quot;&gt;


Starte einen lokalen Webserver, um die index.html Datei anzuzeigen. Zum Beispiel kannst man dies mit Python tun: python -m http.server im Verzeichnis mit der index.html Datei.
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >card-body</code>&quot;&gt;


Öffne deinen Browser und navigiere zu der URL, die deinem lokalen Webserver zugewiesen ist, wie http://localhost:8000, um die interaktive API-Dokumentation deiner Publikationen-Plattform zu sehen.
&lt;<code class="mwt-code" >h5 class=</code>&quot;<code class="mwt-code" >card-title</code>&quot;&gt;<code class="mwt-code" >Publikation 1</code>&lt;<code class="mwt-code" >/h5</code>&gt;


<span id="api-definition-für-unser-fallbeispiel"></span>
&lt;<code class="mwt-code" >p class=</code>&quot;<code class="mwt-code" >card-text</code>&quot;&gt;<code class="mwt-code" >Abstract...</code>&lt;<code class="mwt-code" >/p</code>&gt;
=== API Definition für unser Fallbeispiel ===


In unserem Beispiel könnte man sich folgende vereinfachte API Definitionen vorstellen:
&lt;<code class="mwt-code" >/div</code>&gt;


POST /register
&lt;<code class="mwt-code" >/div</code>&gt;


POST /login
&lt;<code class="mwt-code" >/div</code>&gt;


POST /publications
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >col-md-4 mb-4</code>&quot;&gt;


GET /publications/{id}
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >card</code>&quot;&gt;


POST /reviews
&lt;<code class="mwt-code" >div class=</code>&quot;<code class="mwt-code" >card-body</code>&quot;&gt;


GET /comments?publicationId={id}
&lt;<code class="mwt-code" >h5 class=</code>&quot;<code class="mwt-code" >card-title</code>&quot;&gt;<code class="mwt-code" >Publikation 2</code>&lt;<code class="mwt-code" >/h5</code>&gt;


POST erstellt neue Daten auf dem Server. PUT aktualisiert bestehende Daten. GET ruft Daten vom Server ab, ohne sie zu ändern. Im Frontend Development ist sollte man immer die gesamte Applikation verstehen und wie die Daten am effizientesten zwischen dem Server und dem Frontend ausgetauscht werden können. Deshalb ist es wichtig sich die API-Definition, sowie das UI-Design, am Anfang eines neuen Frontendprojekts gut zu überlegen. Die API-Definition ist der Vertrag zwischen der UI und dem Server. Sehen wir uns nun die Datenübertragung für ein paar Endpunkte im Detail an.
&lt;<code class="mwt-code" >p class=</code>&quot;<code class="mwt-code" >card-text</code>&quot;&gt;<code class="mwt-code" >Abstract...</code>&lt;<code class="mwt-code" >/p</code>&gt;


# POST /register
&lt;<code class="mwt-code" >/div</code>&gt;


'''Beschreibung:''' Registriert einen neuen Benutzer im System.
&lt;<code class="mwt-code" >/div</code>&gt;


<blockquote>'''Anfrage:'''
&lt;<code class="mwt-code" >/div</code>&gt;


{
&lt;<code class="mwt-code" >!-- Weitere Publikationen --</code>&gt;


&quot;username&quot;: &quot;alice&quot;,
&lt;<code class="mwt-code" >/div</code>&gt;


&quot;email&quot;: &quot;alice@example.com&quot;,
&lt;<code class="mwt-code" >/div</code>&gt;


&quot;password&quot;: &quot;securepassword&quot;,
In diesem Beispiel verwendet die Plattform Bootstrap-Klassen wie container, row und col-md-4, um ein responsives Raster zu erstellen, das sich je nach Bildschirmgröße anpasst. Bootstrap sorgt dafür, dass das Layout auf großen Bildschirmen in drei Spalten und auf kleineren Bildschirmen in einer oder zwei Spalten angezeigt wird. Durch die Kombination von Medienabfragen und CSS-Frameworks kann man sicherstellen, dass deine Plattform zur Veröffentlichung wissenschaftlicher Publikationen auf verschiedenen Geräten gut aussieht und benutzerfreundlich ist.


&quot;role&quot;: &quot;Author&quot;
<span id="leistungsoptimierung"></span>
= Leistungsoptimierung =


}
Niemand wartet gerne mehrere Sekunden, bis eine Website vollständig geladen ist. Jede Website, die wir entwickeln sollte, immer so optimiert wie möglich sein. Performance-Benchmarks messen, wie schnell und gut eine Website läuft. Sie helfen dabei, die Benutzererfahrung zu verbessern. Es ist ratsam die Performance einer Website immer wieder zu messen, um sicherzugehen dass man Ladezeiten mit neuen Grafiken oder anderen Elementen unnötig verlängert hat.


'''Antwort:'''
<span id="optimierung-von-ladezeiten"></span>
== Optimierung von Ladezeiten ==


{
'''Szenario:''' Die Seite lädt eine Liste von Publikationen, einschließlich Titel, Abstract und Inhaltszusammenfassung.


&quot;id&quot;: 1,
'''Wir haben folgende Optimierungsmöglichkeiten:'''


&quot;username&quot;: &quot;alice&quot;,
Lazy Loading: Lade Inhalte nur dann, wenn sie tatsächlich benötigt werden. Anstatt alle Publikationen auf einmal zu laden, zeige zunächst nur eine Übersicht an und lade detaillierte Informationen erst, wenn der Benutzer mehr darüber erfahren möchte. Dies reduziert die anfängliche Ladezeit erheblich.


&quot;email&quot;: &quot;alice@example.com&quot;,
Caching: Verwende Browser-Caching oder serverseitiges Caching, um häufig abgerufene Daten zwischenzuspeichern. Wenn eine Publikation einmal abgerufen wurde, speichere diese Daten lokal oder auf dem Server, um sie bei zukünftigen Anfragen schneller bereitstellen zu können. Dies vermindert die Notwendigkeit, dieselben Daten wiederholt vom Server abzurufen.


&quot;role&quot;: &quot;Author&quot;
Minimierung von HTTP-Anfragen''':''' Reduziere die Anzahl der HTTP-Anfragen durch das Zusammenfassen von CSS- und JavaScript-Dateien. Anstatt mehrere Dateien zu laden, kombiniere sie in einer einzigen Datei, um die Anzahl der Anfragen zu minimieren und die Ladezeit zu verkürzen.


}
Komprimierung: Komprimiere die Daten, die zwischen Server und Client ausgetauscht werden. Verwende Gzip oder Brotli-Komprimierung, um die Größe der übertragenen Daten zu reduzieren. Dies verringert die Menge an Daten, die heruntergeladen werden müssen, und beschleunigt die Ladezeiten.
</blockquote>
<ol start="2" style="list-style-type: decimal;">
<li><p>POST /login</p></li></ol>


<blockquote>'''Beschreibung:''' Authentifiziert einen Benutzer und erstellt eine Sitzung.
Optimierung von Bildern''':''' Stelle sicher, dass alle Bilder auf der Website komprimiert und in einem Web-freundlichen Format vorliegen. Verwende Formate wie WebP oder JPEG 2000, die eine bessere Komprimierung bieten, um die Größe der Bilddateien zu reduzieren und die Ladezeiten zu verbessern.


'''Anfrage:'''
Content Delivery Network (CDN): Nutze ein CDN, um statische Dateien wie Bilder, CSS und JavaScript von Servern in der Nähe des Benutzers zu liefern. Ein CDN kann die Ladezeiten durch geografische Verteilung und schnelle Bereitstellung von Inhalten verbessern.


{
<span id="lazy-loading"></span>
===  Lazy Loading ===


&quot;email&quot;: &quot;alice@example.com&quot;,
Lade Publikationen nur bei Bedarf, nicht alle auf einmal. Hier wird zunächst nur eine Übersicht oder ein Teaser angezeigt, und detaillierte Informationen werden erst geladen, wenn der Benutzer auf „Mehr lesen“ klickt oder scrollt.


&quot;password&quot;: &quot;securepassword&quot;
<code class="mwt-code" >// Funktion zum Laden der Details einer Publikation auf Knopfdruck</code>


}
<code class="mwt-code" >async function loadPublikationDetails(publikationId) {</code>


'''Antwort:'''
<code class="mwt-code" >try {</code>


{
<code class="mwt-code" >const response = await fetch(`https://api.example.com/publikationen/${publikationId}`);</code>


&quot;token&quot;: &quot;jwt-token-string&quot;
<code class="mwt-code" >if (!response.ok) {</code>


}
<code class="mwt-code" >throw new Error('Netzwerkantwort war nicht okay.');</code>
</blockquote>
<ol start="3" style="list-style-type: decimal;">
<li><p>POST /publications</p></li></ol>


'''Beschreibung:'''Erstellt eine neue wissenschaftliche Publikation.
<code class="mwt-code" >}</code>


'''Anfrage:'''
<code class="mwt-code" >const data = await response.json();</code>


{
<code class="mwt-code" >displayPublikationDetails(data);</code>


&quot;title&quot;: &quot;Einfluss von KI auf Peer-Review-Prozesse&quot;,
<code class="mwt-code" >} catch (error) {</code>


&quot;abstract&quot;: &quot;Diese Arbeit untersucht...&quot;,
<code class="mwt-code" >console.error('Fehler beim Abrufen der Publikation:', error);</code>


&quot;content&quot;: &quot;Der komplette Inhalt...&quot;,
<code class="mwt-code" >}</code>


&quot;authorId&quot;: 1
<code class="mwt-code" >}</code>


}
<code class="mwt-code" >// Event-Handler für </code>&quot;<code class="mwt-code" >Mehr lesen</code>&quot;<code class="mwt-code" > Button</code>


'''Antwort:'''
<code class="mwt-code" >document.querySelectorAll('.more-info').forEach(button =</code>&gt;<code class="mwt-code" > {</code>


{
<code class="mwt-code" >button.addEventListener('click', () =</code>&gt;<code class="mwt-code" > {</code>


&quot;id&quot;: 101,
<code class="mwt-code" >const publikationId = button.getAttribute('data-id');</code>


&quot;title&quot;: &quot;Einfluss von KI auf Peer-Review-Prozesse&quot;,
<code class="mwt-code" >loadPublikationDetails(publikationId);</code>


&quot;status&quot;: &quot;Eingereicht&quot;
<code class="mwt-code" >});</code>


}
<code class="mwt-code" >});</code>


<ol start="4" style="list-style-type: decimal;">
<span id="caching"></span>
<li><p>GET /publications/{id}</p></li></ol>
=== Caching ===


<blockquote>'''Beschreibung:''' Gibt Details zu einer spezifischen Publikation zurück.
Nutze Browser-Caching, um die Daten von Publikationen zwischenzuspeichern. Bei wiederholten Anfragen können die gecachten Daten verwendet werden, anstatt sie erneut vom Server abzurufen.


'''Parameter:'''
<code class="mwt-code" >// Funktion zum Abrufen der Publikationen mit Caching</code>
</blockquote>
* id (Pfadparameter): Die ID der Publikation.


<blockquote>'''Antwort:'''
<code class="mwt-code" >async function fetchPublikationen() {</code>


{
<code class="mwt-code" >const cacheKey = 'publikationen-cache';</code>


&quot;id&quot;: 101,
<code class="mwt-code" >const cachedData = localStorage.getItem(cacheKey);</code>


&quot;title&quot;: &quot;Einfluss von KI auf Peer-Review-Prozesse&quot;,
<code class="mwt-code" >if (cachedData) {</code>


&quot;abstract&quot;: &quot;Diese Arbeit untersucht...&quot;,
<code class="mwt-code" >return JSON.parse(cachedData); // Rückgabe der gecachten Daten</code>


&quot;content&quot;: &quot;Der komplette Inhalt...&quot;,
<code class="mwt-code" >}</code>


&quot;status&quot;: &quot;Eingereicht&quot;,
<code class="mwt-code" >try {</code>


&quot;authorId&quot;: 1
<code class="mwt-code" >const response = await fetch('https://api.example.com/publikationen');</code>


}
<code class="mwt-code" >if (!response.ok) {</code>
</blockquote>
<ol start="5" style="list-style-type: decimal;">
<li><p>POST /reviews</p></li></ol>


<blockquote>'''Beschreibung:''' Ein Gutachter erstellt ein Gutachten für eine Publikation.
<code class="mwt-code" >throw new Error('Netzwerkantwort war nicht okay.');</code>


'''Anfrage:'''
<code class="mwt-code" >}</code>


{
<code class="mwt-code" >const data = await response.json();</code>


&quot;publicationId&quot;: 101,
<code class="mwt-code" >localStorage.setItem(cacheKey, JSON.stringify(data)); // Speichern in lokalem Speicher</code>


&quot;reviewerId&quot;: 2,
<code class="mwt-code" >return data;</code>


&quot;comments&quot;: &quot;Die Arbeit ist gut, aber...&quot;,
<code class="mwt-code" >} catch (error) {</code>


&quot;recommendation&quot;: &quot;Kleine Überarbeitung&quot;
<code class="mwt-code" >console.error('Fehler beim Abrufen der Publikationen:', error);</code>


}
<code class="mwt-code" >}</code>


'''Antwort:'''
<code class="mwt-code" >}</code>


{
<span id="minimierung-von-http-anfragen"></span>
=== Minimierung von HTTP-Anfragen ===


&quot;id&quot;: 201,
Kombiniere mehrere CSS- und JavaScript-Dateien zu einer einzigen Datei, um die Anzahl der HTTP-Anfragen zu reduzieren.


&quot;publicationId&quot;: 101,
&lt;<code class="mwt-code" >!-- Kombinierte CSS-Datei --</code>&gt;


&quot;reviewerId&quot;: 2,
&lt;<code class="mwt-code" >link rel=</code>&quot;<code class="mwt-code" >stylesheet</code>&quot;<code class="mwt-code" > href=</code>&quot;<code class="mwt-code" >styles.min.css</code>&quot;&gt;


&quot;status&quot;: &quot;Gutachten erstellt&quot;
&lt;<code class="mwt-code" >!-- Kombinierte JavaScript-Datei --</code>&gt;


}
&lt;<code class="mwt-code" >script src=</code>&quot;<code class="mwt-code" >scripts.min.js</code>&quot;&gt;&lt;<code class="mwt-code" >/script</code>&gt;
</blockquote>
<ol start="6" style="list-style-type: decimal;">
<li><p>GET /comments?publicationId={id}</p></li></ol>


<blockquote>'''Beschreibung:''' Listet alle Kommentare zu einer Publikation auf.
Verwende Build-Tools wie Webpack oder Gulp, um deine CSS- und JavaScript-Dateien zu bündeln und zu minimieren.


'''Parameter:'''
<span id="komprimierung"></span>
</blockquote>
=== Komprimierung ===
* publicationId (Query-Parameter): Die ID der Publikation.


<blockquote>'''Antwort:'''
Aktiviere Gzip-Komprimierung auf deinem Webserver, um die Größe der übertragenen Daten zu reduzieren.


[
Beispielsweise kann man dies in der Apache-Konfiguration folgendermaßen machen:


{
&lt;<code class="mwt-code" >IfModule mod_deflate.c</code>&gt;


&quot;id&quot;: 301,
<code class="mwt-code" >AddOutputFilterByType DEFLATE text/text</code>


&quot;publicationId&quot;: 101,
<code class="mwt-code" >AddOutputFilterByType DEFLATE text/html</code>


&quot;userId&quot;: 3,
<code class="mwt-code" >AddOutputFilterByType DEFLATE text/xml</code>


&quot;content&quot;: &quot;Sehr interessante Ergebnisse!&quot;
<code class="mwt-code" >AddOutputFilterByType DEFLATE text/css</code>


},
<code class="mwt-code" >AddOutputFilterByType DEFLATE application/xml</code>


{
<code class="mwt-code" >AddOutputFilterByType DEFLATE application/xhtml+xml</code>


&quot;id&quot;: 302,
<code class="mwt-code" >AddOutputFilterByType DEFLATE application/rss+xml</code>


&quot;publicationId&quot;: 101,
<code class="mwt-code" >AddOutputFilterByType DEFLATE application/javascript</code>


&quot;userId&quot;: 4,
<code class="mwt-code" >AddOutputFilterByType DEFLATE application/x-javascript</code>


&quot;content&quot;: &quot;Ich stimme dem Gutachter zu, aber...&quot;
&lt;<code class="mwt-code" >/IfModule</code>&gt;


}
<span id="optimierung-von-bildern"></span>
=== Optimierung von Bildern ===
 
Verwende komprimierte Bildformate wie WebP, um die Größe der Bilddateien zu reduzieren.


]
&lt;<code class="mwt-code" >!-- WebP-Bild verwenden --</code>&gt;
</blockquote>
<span id="alternative-tools"></span>
=== Alternative Tools ===


Es gibt auch online Tools zur API-Dokumentation. Beispielsweise:
&lt;<code class="mwt-code" >img src=</code>&quot;<code class="mwt-code" >publikationen-image.webp</code>&quot;<code class="mwt-code" > alt=</code>&quot;<code class="mwt-code" >Publikationsbild</code>&quot;&gt;


* Swagger Editor (SmartBear, 2024): Besuche Swagger Editor, lade eine OpenAPI-Spezifikation hoch oder füge den Inhalt direkt ein, um die API-Dokumentation zu erstellen und zu testen.
<span id="content-delivery-network-cdn"></span>
* Postman (Postman, Inc., 2024): Lade eine OpenAPI-Spezifikation in Postman, um die API-Dokumentation anzuzeigen und API-Anfragen zu testen.
=== Content Delivery Network (CDN) ===


Diese Tools helfen, die API-Dokumentation für die Plattform zu visualisieren und zu überprüfen, wie die API funktioniert.
Nutze ein CDN, um statische Dateien wie Bilder und JavaScript von Servern näher am Benutzer bereitzustellen.


<span id="responsive-webdesign"></span>
&lt;<code class="mwt-code" >!-- Bild von einem CDN laden --</code>&gt;
= Responsive Webdesign =


Responsive Webdesign sorgt dafür, dass Websites auf allen Geräten gut aussehen, indem sie sich automatisch an verschiedene Bildschirmgrößen anpassen. Zu den Prinzipien gehören flexible Layouts, die sich an unterschiedliche Bildschirmgrößen anpassen, skalierbare Bilder und Schriften sowie die Verwendung von Media Queries in CSS, um spezifische Stile für verschiedene Geräte zu definieren. Ziel ist es, eine konsistente und nutzerfreundliche Erfahrung auf Smartphones, Tablets und Desktops zu bieten.
&lt;<code class="mwt-code" >img src=</code>&quot;<code class="mwt-code" >https://cdn.example.com/images/publikationen-image.jpg</code>&quot;<code class="mwt-code" > alt=</code>&quot;<code class="mwt-code" >Publikationsbild</code>&quot;&gt;


<span id="gestaltung-von-benutzeroberflächen-die-auf-verschiedenen-geräten-und-bildschirmgrößen-gut-funktionieren"></span>
Durch diese Optimierungen kann man die Ladezeiten deiner Plattform erheblich verbessern und somit die Benutzererfahrung steigern.
== Gestaltung von Benutzeroberflächen, die auf verschiedenen Geräten und Bildschirmgrößen gut funktionieren ==


Sehen wir uns ein paar HTML und CSS-Konzepte an, die es ermöglichen Elemente unterschiedlich auf unterschiedlichen Geräten darzustellen. Die besprochenen JavaScript Frameworks helfen auch dabei Websites zu designen die sowohl auf großen Bildschirmen als auch auf Smartphones gut bedienbar sind.
<span id="ressourcenoptimierung"></span>
== Ressourcenoptimierung ==


<span id="responsive-layout"></span>
Um den Ressourcenverbrauch in einer Webanwendung zu optimieren, kann man verschiedene Techniken anwenden, um die Effizienz der Nutzung von CPU, Speicher und Netzwerkbandbreite zu verbessern. Hier sind einige Beispiele, wie man dies für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen umsetzen kann:
=== Responsive Layout ===


Verwende Flexbox für ein flexibles Layout, das sich an verschiedene Bildschirmgrößen anpasst.
<span id="code-splitting"></span>
=== Code-Splitting ===


&lt;!-- HTML-Struktur --&gt;
Unterteile deinen JavaScript-Code in kleinere, nach Bedarf ladbare Teile. Das reduziert die anfängliche Ladezeit und verbessert die Leistung, da nur der benötigte Code geladen wird.


&lt;div class=&quot;publikationen-container&quot;&gt;
<code class="mwt-code" >// Beispiel mit Webpack für Code-Splitting</code>


&lt;div class=&quot;publikation&quot;&gt;
<code class="mwt-code" >import(/* webpackChunkName: </code>&quot;<code class="mwt-code" >publikation-details</code>&quot;<code class="mwt-code" > */ './publikation-details.js')</code>


&lt;h2&gt;Publikation 1&lt;/h2&gt;
<code class="mwt-code" >.then(module =</code>&gt;<code class="mwt-code" > {</code>


&lt;p&gt;Abstract...&lt;/p&gt;
<code class="mwt-code" >const loadDetails = module.loadDetails;</code>


&lt;/div&gt;
<code class="mwt-code" >loadDetails();</code>


&lt;div class=&quot;publikation&quot;&gt;
<code class="mwt-code" >})</code>


&lt;h2&gt;Publikation 2&lt;/h2&gt;
<code class="mwt-code" >.catch(err =</code>&gt;<code class="mwt-code" > {</code>


&lt;p&gt;Abstract...&lt;/p&gt;
<code class="mwt-code" >console.error('Fehler beim Laden des Moduls:', err);</code>


&lt;/div&gt;
<code class="mwt-code" >});</code>


&lt;!-- Weitere Publikationen --&gt;
<span id="vermeidung-von-übermäßigem-dom-manipulationen"></span>
=== Vermeidung von übermäßigem DOM-Manipulationen ===


&lt;/div&gt;
Reduziere die Anzahl der DOM-Manipulationen, indem man Änderungen in einem Dokumentfragment vornimmt und das Fragment dann einmal in das DOM einfügt.


/* CSS für responsives Layout */
<code class="mwt-code" >// Reduziere DOM-Manipulationen</code>


.publikationen-container {
<code class="mwt-code" >const fragment = document.createDocumentFragment();</code>


display: flex;
<code class="mwt-code" >const list = document.createElement('ul');</code>


flex-wrap: wrap;
<code class="mwt-code" >for (let i = 0; i </code>&lt;<code class="mwt-code" > 100; i++) {</code>


gap: 16px;
<code class="mwt-code" >const item = document.createElement('li');</code>


}
<code class="mwt-code" >item.textContent = `Publikation ${i + 1}`;</code>


.publikation {
<code class="mwt-code" >list.appendChild(item);</code>


flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout mit Abstand */
<code class="mwt-code" >}</code>


box-sizing: border-box;
<code class="mwt-code" >fragment.appendChild(list);</code>


}
<code class="mwt-code" >document.getElementById('publikationen-container').appendChild(fragment);</code>


@media (max-width: 768px) {
<span id="minimierung-von-berechnungen-im-haupt-thread"></span>
=== Minimierung von Berechnungen im Haupt-Thread ===


.publikation {
Verschiebe rechenintensive Aufgaben in Web Worker, um den Haupt-Thread zu entlasten und die Benutzeroberfläche reaktionsfähig zu halten.


flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout auf Tablets */
<code class="mwt-code" >// Haupt-Thread</code>


}
<code class="mwt-code" >const worker = new Worker('worker.js');</code>


}
<code class="mwt-code" >worker.postMessage('start');</code>


@media (max-width: 480px) {
<code class="mwt-code" >// worker.js</code>


.publikation {
<code class="mwt-code" >self.onmessage = function(event) {</code>


flex: 1 1 100%; /* Einspaltiges Layout auf Mobilgeräten */
<code class="mwt-code" >if (event.data === 'start') {</code>


}
<code class="mwt-code" >// Rechenintensive Aufgabe</code>


}
<code class="mwt-code" >let result = performHeavyComputation();</code>


<span id="media-queries"></span>
<code class="mwt-code" >self.postMessage(result);</code>
=== Media Queries ===


Passe Stile für unterschiedliche Bildschirmgrößen an, um das Layout und die Schriftgröße zu optimieren.
<code class="mwt-code" >}</code>


/* Media Queries für unterschiedliche Bildschirmgrößen */
<code class="mwt-code" >};</code>


@media (max-width: 1200px) {
<span id="ressourcenoptimierung-durch-lazy-loading-von-bildern"></span>
=== Ressourcenoptimierung durch Lazy Loading von Bildern ===


.header {
Lade Bilder nur dann, wenn sie in den Sichtbereich des Benutzers kommen, um Bandbreite zu sparen und die Ladezeiten zu verbessern.


font-size: 1.5em;
&lt;<code class="mwt-code" >!-- Verwende `loading=</code>&quot;<code class="mwt-code" >lazy</code>&quot;<code class="mwt-code" >` für Lazy Loading von Bildern --</code>&gt;


}
&lt;<code class="mwt-code" >img src=</code>&quot;<code class="mwt-code" >image.jpg</code>&quot;<code class="mwt-code" > loading=</code>&quot;<code class="mwt-code" >lazy</code>&quot;<code class="mwt-code" > alt=</code>&quot;<code class="mwt-code" >Publikationsbild</code>&quot;&gt;


}
<span id="vermeidung-von-redundanz-bei-netzwerkanfragen"></span>
=== Vermeidung von Redundanz bei Netzwerkanfragen ===


@media (max-width: 768px) {
Nutze ETags und Last-Modified Header zur Validierung von Cache-Inhalten, um unnötige Netzwerkanfragen zu vermeiden.


.header {
<code class="mwt-code" >// Beispiel für einen Server-Response mit ETag</code>


font-size: 1.2em;
<code class="mwt-code" >HTTP/1.1 200 OK</code>


}
<code class="mwt-code" >ETag: </code>&quot;<code class="mwt-code" >123456789</code>&quot;


.navigation {
<code class="mwt-code" >Content-Type: application/json</code>


display: none; /* Navigation auf kleineren Bildschirmen ausblenden */
<code class="mwt-code" >// Client-seitige Validierung</code>


}
<code class="mwt-code" >fetch('https://api.example.com/publikationen', {</code>


}
<code class="mwt-code" >headers: {</code>


<span id="flexible-bilder"></span>
<code class="mwt-code" >'If-None-Match': '123456789' // Verwende den ETag-Wert</code>
=== Flexible Bilder ===


Stelle sicher, dass Bilder sich proportional zur Bildschirmgröße skalieren.
<code class="mwt-code" >}</code>


/* Flexibles Bild */
<code class="mwt-code" >})</code>


img {
<code class="mwt-code" >.then(response =</code>&gt;<code class="mwt-code" > {</code>


max-width: 100%;
<code class="mwt-code" >if (response.status === 304) {</code>


height: auto;
<code class="mwt-code" >console.log('Daten nicht geändert, verwende Cache.');</code>


}
<code class="mwt-code" >} else {</code>


<span id="touchfreundliche-elemente"></span>
<code class="mwt-code" >return response.json();</code>
=== Touchfreundliche Elemente ===


Gestalte Schaltflächen und Links groß genug für eine einfache Bedienung auf Touchscreens.
<code class="mwt-code" >}</code>


/* Touchfreundliche Schaltflächen */
<code class="mwt-code" >});</code>


button {
<span id="effiziente-datenabfragen"></span>
=== Effiziente Datenabfragen ===


padding: 12px 20px;
Wir können API-Anfragen optimieren, indem man nur die benötigten Daten abfragt und die Abfragen entsprechend filtert.


font-size: 16px;
<code class="mwt-code" >// API-Anfrage mit spezifischen Abfrageparametern</code>


}
<code class="mwt-code" >fetch('https://api.example.com/publikationen?fields=titel,abstract')</code>


<span id="testen"></span>
<code class="mwt-code" >.then(response =</code>&gt;<code class="mwt-code" > response.json())</code>
=== Testen ===


Nutze Entwicklertools in Browsern oder echte Geräte, um das Layout und die Funktionalität auf verschiedenen Bildschirmgrößen zu überprüfen. Mit diesen Techniken und Beispielen kannst man sicherstellen, dass unsere Plattform für wissenschaftliche Publikationen auf allen Geräten gut aussieht und benutzerfreundlich ist.
<code class="mwt-code" >.then(data =</code>&gt;<code class="mwt-code" > {</code>


<span id="medienabfragen-und-die-verwendung-von-css-frameworks-zur-unterstützung-des-responsiven-designs"></span>
<code class="mwt-code" >console.log(data);</code>
== Medienabfragen und die Verwendung von CSS-Frameworks zur Unterstützung des responsiven Designs ==


<span id="medienabfragen"></span>
<code class="mwt-code" >});</code>
=== Medienabfragen ===


Medienabfragen ermöglichen es, CSS-Stile basierend auf den Eigenschaften des Geräts wie Bildschirmgröße und -auflösung anzupassen. Sie sind besonders nützlich, um sicherzustellen, dass deine Plattform auf verschiedenen Bildschirmgrößen gut aussieht.
<span id="optimierung-der-bildgröße"></span>
=== Optimierung der Bildgröße ===


'''Beispiel:''' Wir möchten das Layout der Publikationen auf unterschiedlichen Geräten anpassen.
Verwende Bildkomprimierung und -optimierung, um die Dateigröße zu reduzieren, ohne die Bildqualität merklich zu beeinträchtigen.<pre>
&lt;!-- Komprimiertes Bild verwenden --&gt;
&lt;img src="publikationen-image-compressed.jpg" alt="Publikationsbild"&gt;
</pre>


/* Standardlayout für große Bildschirme */
Durch diese Techniken kann man den Ressourcenverbrauch deiner Anwendung senken, die Leistung verbessern und eine flüssigere Benutzererfahrung bieten.


.publikationen-container {
<span id="bibliography"></span>
 
display: flex;
 
flex-wrap: wrap;


gap: 16px;
}
.publikation {
flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout für große Bildschirme */
box-sizing: border-box;
}
/* Layout für Tablets */
@media (max-width: 768px) {
.publikation {
flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout für Tablets */
}
}
/* Layout für Mobilgeräte */
@media (max-width: 480px) {
.publikation {
flex: 1 1 100%; /* Einspaltiges Layout für Mobilgeräte */
}
}
<span id="verwendung-von-css-frameworks"></span>
=== Verwendung von CSS-Frameworks ===
CSS-Frameworks bieten vorgefertigte Klassen und Komponenten, die helfen, responsives Design schnell und einfach zu implementieren. Beliebte Frameworks sind Bootstrap, Foundation und Tailwind CSS.
Bootstrap ist ein weit verbreitetes CSS-Framework, das eine Reihe von nützlichen Klassen für responsives Design bereitstellt. Füge die Bootstrap CSS-Datei in deinem HTML-Dokument ein.
&lt;!-- Bootstrap CSS einbinden --&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css&quot;&gt;
Verwende Bootstrap-Klassen, um ein responsives Layout für deine Publikationen zu erstellen.
&lt;!-- HTML-Struktur mit Bootstrap-Klassen --&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;div class=&quot;row&quot;&gt;
&lt;div class=&quot;col-md-4 mb-4&quot;&gt;
&lt;div class=&quot;card&quot;&gt;
&lt;div class=&quot;card-body&quot;&gt;
&lt;h5 class=&quot;card-title&quot;&gt;Publikation 1&lt;/h5&gt;
&lt;p class=&quot;card-text&quot;&gt;Abstract...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;col-md-4 mb-4&quot;&gt;
&lt;div class=&quot;card&quot;&gt;
&lt;div class=&quot;card-body&quot;&gt;
&lt;h5 class=&quot;card-title&quot;&gt;Publikation 2&lt;/h5&gt;
&lt;p class=&quot;card-text&quot;&gt;Abstract...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- Weitere Publikationen --&gt;
&lt;/div&gt;
&lt;/div&gt;
In diesem Beispiel verwendet die Plattform Bootstrap-Klassen wie container, row und col-md-4, um ein responsives Raster zu erstellen, das sich je nach Bildschirmgröße anpasst. Bootstrap sorgt dafür, dass das Layout auf großen Bildschirmen in drei Spalten und auf kleineren Bildschirmen in einer oder zwei Spalten angezeigt wird. Durch die Kombination von Medienabfragen und CSS-Frameworks kann man sicherstellen, dass deine Plattform zur Veröffentlichung wissenschaftlicher Publikationen auf verschiedenen Geräten gut aussieht und benutzerfreundlich ist.
<span id="leistungsoptimierung"></span>
= Leistungsoptimierung =
Niemand wartet gerne mehrere Sekunden, bis eine Website vollständig geladen ist. Jede Website, die wir entwickeln sollte, immer so optimiert wie möglich sein. Performance-Benchmarks messen, wie schnell und gut eine Website läuft. Sie helfen dabei, die Benutzererfahrung zu verbessern. Es ist ratsam die Performance einer Website immer wieder zu messen, um sicherzugehen dass man Ladezeiten mit neuen Grafiken oder anderen Elementen unnötig verlängert hat.
<span id="optimierung-von-ladezeiten"></span>
== Optimierung von Ladezeiten ==
'''Szenario:''' Die Seite lädt eine Liste von Publikationen, einschließlich Titel, Abstract und Inhaltszusammenfassung.
'''Wir haben folgende Optimierungsmöglichkeiten:'''
Lazy Loading: Lade Inhalte nur dann, wenn sie tatsächlich benötigt werden. Anstatt alle Publikationen auf einmal zu laden, zeige zunächst nur eine Übersicht an und lade detaillierte Informationen erst, wenn der Benutzer mehr darüber erfahren möchte. Dies reduziert die anfängliche Ladezeit erheblich.
Caching: Verwende Browser-Caching oder serverseitiges Caching, um häufig abgerufene Daten zwischenzuspeichern. Wenn eine Publikation einmal abgerufen wurde, speichere diese Daten lokal oder auf dem Server, um sie bei zukünftigen Anfragen schneller bereitstellen zu können. Dies vermindert die Notwendigkeit, dieselben Daten wiederholt vom Server abzurufen.
Minimierung von HTTP-Anfragen''':''' Reduziere die Anzahl der HTTP-Anfragen durch das Zusammenfassen von CSS- und JavaScript-Dateien. Anstatt mehrere Dateien zu laden, kombiniere sie in einer einzigen Datei, um die Anzahl der Anfragen zu minimieren und die Ladezeit zu verkürzen.
Komprimierung: Komprimiere die Daten, die zwischen Server und Client ausgetauscht werden. Verwende Gzip oder Brotli-Komprimierung, um die Größe der übertragenen Daten zu reduzieren. Dies verringert die Menge an Daten, die heruntergeladen werden müssen, und beschleunigt die Ladezeiten.
Optimierung von Bildern''':''' Stelle sicher, dass alle Bilder auf der Website komprimiert und in einem Web-freundlichen Format vorliegen. Verwende Formate wie WebP oder JPEG 2000, die eine bessere Komprimierung bieten, um die Größe der Bilddateien zu reduzieren und die Ladezeiten zu verbessern.
Content Delivery Network (CDN): Nutze ein CDN, um statische Dateien wie Bilder, CSS und JavaScript von Servern in der Nähe des Benutzers zu liefern. Ein CDN kann die Ladezeiten durch geografische Verteilung und schnelle Bereitstellung von Inhalten verbessern.
<span id="lazy-loading"></span>
===  Lazy Loading ===
Lade Publikationen nur bei Bedarf, nicht alle auf einmal. Hier wird zunächst nur eine Übersicht oder ein Teaser angezeigt, und detaillierte Informationen werden erst geladen, wenn der Benutzer auf „Mehr lesen“ klickt oder scrollt.
// Funktion zum Laden der Details einer Publikation auf Knopfdruck
async function loadPublikationDetails(publikationId) {
try {
const response = await fetch(`https://api.example.com/publikationen/${publikationId}`);
if (!response.ok) {
throw new Error('Netzwerkantwort war nicht okay.');
}
const data = await response.json();
displayPublikationDetails(data);
} catch (error) {
console.error('Fehler beim Abrufen der Publikation:', error);
}
}
// Event-Handler für &quot;Mehr lesen&quot; Button
document.querySelectorAll('.more-info').forEach(button =&gt; {
button.addEventListener('click', () =&gt; {
const publikationId = button.getAttribute('data-id');
loadPublikationDetails(publikationId);
});
});
<span id="caching"></span>
=== Caching ===
Nutze Browser-Caching, um die Daten von Publikationen zwischenzuspeichern. Bei wiederholten Anfragen können die gecachten Daten verwendet werden, anstatt sie erneut vom Server abzurufen.
// Funktion zum Abrufen der Publikationen mit Caching
async function fetchPublikationen() {
const cacheKey = 'publikationen-cache';
const cachedData = localStorage.getItem(cacheKey);
if (cachedData) {
return JSON.parse(cachedData); // Rückgabe der gecachten Daten
}
try {
const response = await fetch('https://api.example.com/publikationen');
if (!response.ok) {
throw new Error('Netzwerkantwort war nicht okay.');
}
const data = await response.json();
localStorage.setItem(cacheKey, JSON.stringify(data)); // Speichern in lokalem Speicher
return data;
} catch (error) {
console.error('Fehler beim Abrufen der Publikationen:', error);
}
}
<span id="minimierung-von-http-anfragen"></span>
=== Minimierung von HTTP-Anfragen ===
Kombiniere mehrere CSS- und JavaScript-Dateien zu einer einzigen Datei, um die Anzahl der HTTP-Anfragen zu reduzieren.
&lt;!-- Kombinierte CSS-Datei --&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;styles.min.css&quot;&gt;
&lt;!-- Kombinierte JavaScript-Datei --&gt;
&lt;script src=&quot;scripts.min.js&quot;&gt;&lt;/script&gt;
Verwende Build-Tools wie Webpack oder Gulp, um deine CSS- und JavaScript-Dateien zu bündeln und zu minimieren.
<span id="komprimierung"></span>
=== Komprimierung ===
Aktiviere Gzip-Komprimierung auf deinem Webserver, um die Größe der übertragenen Daten zu reduzieren.
# In der Apache-Konfiguration aktivieren
&lt;IfModule mod_deflate.c&gt;
AddOutputFilterByType DEFLATE text/text
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
&lt;/IfModule&gt;
<span id="optimierung-von-bildern"></span>
=== Optimierung von Bildern ===
Verwende komprimierte Bildformate wie WebP, um die Größe der Bilddateien zu reduzieren.
&lt;!-- WebP-Bild verwenden --&gt;
&lt;img src=&quot;publikationen-image.webp&quot; alt=&quot;Publikationsbild&quot;&gt;
<span id="content-delivery-network-cdn"></span>
=== Content Delivery Network (CDN) ===
Nutze ein CDN, um statische Dateien wie Bilder und JavaScript von Servern näher am Benutzer bereitzustellen.
&lt;!-- Bild von einem CDN laden --&gt;
&lt;img src=&quot;https://cdn.example.com/images/publikationen-image.jpg&quot; alt=&quot;Publikationsbild&quot;&gt;
Durch diese Optimierungen kann man die Ladezeiten deiner Plattform erheblich verbessern und somit die Benutzererfahrung steigern.
<span id="ressourcenoptimierung"></span>
== Ressourcenoptimierung ==
Um den Ressourcenverbrauch in einer Webanwendung zu optimieren, kann man verschiedene Techniken anwenden, um die Effizienz der Nutzung von CPU, Speicher und Netzwerkbandbreite zu verbessern. Hier sind einige Beispiele, wie man dies für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen umsetzen kann:
<span id="code-splitting"></span>
=== Code-Splitting ===
Unterteile deinen JavaScript-Code in kleinere, nach Bedarf ladbare Teile. Das reduziert die anfängliche Ladezeit und verbessert die Leistung, da nur der benötigte Code geladen wird.
// Beispiel mit Webpack für Code-Splitting
import(/* webpackChunkName: &quot;publikation-details&quot; */ './publikation-details.js')
.then(module =&gt; {
const loadDetails = module.loadDetails;
loadDetails();
})
.catch(err =&gt; {
console.error('Fehler beim Laden des Moduls:', err);
});
<span id="vermeidung-von-übermäßigem-dom-manipulationen"></span>
=== Vermeidung von übermäßigem DOM-Manipulationen ===
Reduziere die Anzahl der DOM-Manipulationen, indem man Änderungen in einem Dokumentfragment vornimmt und das Fragment dann einmal in das DOM einfügt.
// Reduziere DOM-Manipulationen
const fragment = document.createDocumentFragment();
const list = document.createElement('ul');
for (let i = 0; i &lt; 100; i++) {
const item = document.createElement('li');
item.textContent = `Publikation ${i + 1}`;
list.appendChild(item);
}
fragment.appendChild(list);
document.getElementById('publikationen-container').appendChild(fragment);
<span id="minimierung-von-berechnungen-im-haupt-thread"></span>
=== Minimierung von Berechnungen im Haupt-Thread ===
Verschiebe rechenintensive Aufgaben in Web Worker, um den Haupt-Thread zu entlasten und die Benutzeroberfläche reaktionsfähig zu halten.
// Haupt-Thread
const worker = new Worker('worker.js');
worker.postMessage('start');
// worker.js
self.onmessage = function(event) {
if (event.data === 'start') {
// Rechenintensive Aufgabe
let result = performHeavyComputation();
self.postMessage(result);
}
};
<span id="ressourcenoptimierung-durch-lazy-loading-von-bildern"></span>
=== Ressourcenoptimierung durch Lazy Loading von Bildern ===
Lade Bilder nur dann, wenn sie in den Sichtbereich des Benutzers kommen, um Bandbreite zu sparen und die Ladezeiten zu verbessern.
&lt;!-- Verwende `loading=&quot;lazy&quot;` für Lazy Loading von Bildern --&gt;
&lt;img src=&quot;image.jpg&quot; loading=&quot;lazy&quot; alt=&quot;Publikationsbild&quot;&gt;
<span id="vermeidung-von-redundanz-bei-netzwerkanfragen"></span>
=== Vermeidung von Redundanz bei Netzwerkanfragen ===
Nutze ETags und Last-Modified Header zur Validierung von Cache-Inhalten, um unnötige Netzwerkanfragen zu vermeiden.
// Beispiel für einen Server-Response mit ETag
HTTP/1.1 200 OK
ETag: &quot;123456789&quot;
Content-Type: application/json
// Client-seitige Validierung
fetch('https://api.example.com/publikationen', {
headers: {
'If-None-Match': '123456789' // Verwende den ETag-Wert
}
})
.then(response =&gt; {
if (response.status === 304) {
console.log('Daten nicht geändert, verwende Cache.');
} else {
return response.json();
}
});
<span id="effiziente-datenabfragen"></span>
=== Effiziente Datenabfragen ===
Wir können API-Anfragen optimieren, indem man nur die benötigten Daten abfragt und die Abfragen entsprechend filtert.
// API-Anfrage mit spezifischen Abfrageparametern
fetch('https://api.example.com/publikationen?fields=titel,abstract')
.then(response =&gt; response.json())
.then(data =&gt; {
console.log(data);
});
<span id="optimierung-der-bildgröße"></span>
=== Optimierung der Bildgröße ===
Verwende Bildkomprimierung und -optimierung, um die Dateigröße zu reduzieren, ohne die Bildqualität merklich zu beeinträchtigen.
&lt;!-- Komprimiertes Bild verwenden --&gt;
&lt;img src=&quot;publikationen-image-compressed.jpg&quot; alt=&quot;Publikationsbild&quot;&gt;
Durch diese Techniken kann man den Ressourcenverbrauch deiner Anwendung senken, die Leistung verbessern und eine flüssigere Benutzererfahrung bieten.
<span id="bibliography"></span>
= Bibliography =
= Bibliography =



Aktuelle Version vom 26. September 2024, 21:39 Uhr

Vorwort

Es ist 2024. Softwareentwicklung verändert sich gerade in einer Weise wie ich es seit meinem ersten Kontakt mit dieser Disziplin um das Jahr 2010 nicht erlebt habe. ChatBots und KI-gestützte Tools verändern, wie man Softwareprojekte angeht. OpenAIs ChatGPT (OpenAI, 2024) und GitHubs CoPilot (CoPilot, 2024) sind disruptive Technologien, die es Entwickler*innen ermöglichen sich mehr auf die Softwarearchitektur und das große Ganze zu konzentrieren und Unterstützung bei der Detailarbeit zu erhalten.

Eines bleibt, wie es immer war: Es gibt nur einen Weg, Programmieren zu lernen, und dieser heißt: selbst zu programmieren. Dieses Studienheft zu lesen, wird niemandem programmieren beibringen. Softwareentwicklung, egal mit welcher Programmiersprache, kann man nur durch Praxis erlernen und vertiefen. Was mich bei Lehrbüchern oft gestört hat, war, dass oft eine Sprache und deren Konzepte erklärt wurden, aber nicht, wie der ganze Prozess von Anfang bis zum Ende funktioniert. Deshalb beginnen wir in diesem Fach mit dem Setup und dem Tooling, welches für ein Frontendprojekt notwendig ist und in der Praxis verwendet wird.

Das Setup

Bevor wir uns mit JavaScript befassen, richten wir das Entwicklungssetup ein und lernen nützliche Werkzeuge kennen, die das Programmieren erleichtern. Ein lokal laufendes Programm ist zwar gut, kann aber meistens von niemand anderem einfach verwendet werden. Programmieren ist ein Teamsport. Deshalb beginnen wir mit Versionskontrollsystemen, GitHub und der Entwicklungsumgebung. Falls das alles bereits bekannt ist und bereits ein Frontend-Development-Setup vorhanden ist können die nächsten Kapitel überflogen werden und es kann mit der Erstellung des GitHub-Repositories begonnen werden.

Git

Git (git, 2024) ist ein Versionskontrollsystem (VCS), das die Verwaltung von Quellcode ermöglicht. Es speichert Änderungen an Dateien und erlaubt es, auf frühere Versionen zurückzugreifen. Zuerst gehen wir einige Begriffe durch, und danach werden wir es anwenden und ein GitHub-Repository erstellen. Selbst wenn man allein programmiert, bringt die Verwendung eines VCS Vorteile.

Repository

Ein Repository (Repo) ist ein Speicherort für den Quellcode eines Projekts. Es enthält alle Dateien und Verzeichnisse des Projekts sowie die gesamte Historie der Änderungen.

Lokal: Ein lokales Repository befindet sich auf deinem Computer.

Remote: Ein Remote-Repository befindet sich auf einem Server (z.B. GitHub (GitHub, 2024), GitLab (GitLab, 2024) oder BitBucket (BitBucket, 2024)).

Commit

Ein Commit ist eine gespeicherte Version des Projekts. Jeder Commit hat eine eindeutige ID und enthält eine Nachricht, die die vorgenommenen Änderungen beschreibt.

git commit -m "Beschreibung der Änderung"

Branch

Ein Branch ist ein unabhängiger Entwicklungszweig innerhalb des Repositories. Der Hauptbranch heißt meist main.

git branch <branch-name>

Merge

Merging kombiniert die Änderungen aus einem Branch mit einem anderen. Oft wird ein Feature-Branch in den Hauptbranch gemergt.

git merge <branch-name>

Konflikte

Konflikte entstehen, wenn Änderungen in verschiedenen Branches kollidieren. Git kann diese nicht automatisch zusammenführen, sodass eine manuelle Auflösung erforderlich ist.

Staging Area

Die Staging Area ist eine Zwischenschicht zwischen den Dateien im Arbeitsverzeichnis und dem Repository. Änderungen müssen zur Staging Area hinzugefügt werden, bevor sie committet werden.

git add <datei-name>

Remote Repository

Ein Remote-Repository ist eine gehostete Version eines Repositories.

  • Push: Änderungen von lokal nach remote senden.

    git push origin <branch-name>

  • Pull: Änderungen von remote nach lokal holen.

    git pull origin <branch-name>

Pull Requests (PR) / Merge Requests (MR)

Ein PR oder MR ist eine Anfrage zur Überprüfung und Integration von Änderungen von einem Branch in einen anderen. In der Praxis ist es üblich, dass ein PR von mehreren Entwicklern überprüft wird bevor dieser gemergt wird. In dieser Lehrveranstaltung muss immer ein PR für jede Änderung des Quellcodes erstellt werden.

Tags

Tags sind feste Referenzpunkte im Verlauf eines Projekts. Sie werden oft verwendet, um Versionen zu markieren (z.B. v1.0.0).

git tag <tag-name>

Weiterführende Links

GitHub

GitHub (GitHub, 2024) ist eine web-basierte Plattform, welche Git-Repositories hostet und zusätzliche Funktionen für die Zusammenarbeit und das Projektmanagement bietet. Es wird häufig von Entwicklern verwendet, um Quellcode zu speichern, zu verwalten und gemeinsam zu bearbeiten.

Alles beginnt mit einem Repo

Gehen wir das Gelernte nun an einem Beispiel durch. Die Erstellung eines Repos in einer der oben genannten Plattformen sollte immer der erste Schritt eines jeden Softwareprojekts sein. In dieser Lehrveranstaltung verwenden wir GitHub.

Bevor wir beginnen, schauen wir uns an wo wir hinwollen. Ein Repo sollte eine gute “README.md“ Datei haben, welche erklärt wie man das Projekt verwenden kann. .md steht dabei für Markdown (Markdown, 2024). Markdown ist ein Markup-Sprache, die zum Formatieren von Dokumenten verwendet wird. Hier ein paar Beispiele von gut strukturierten Repos und READMEs.

Gute READMEs enthalten eine Beschreibung, worum es bei dem Softwareprojekt geht, wie man es verwendet, wie man etwas beisteuern kann sowie Lizenzen. Erstellen wir nun ein GitHub Konto und ein erstes Repo. Falls git noch nicht installiert ist, können wir dieser Anleitung folgen: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git.

Konto erstellen:

  • Gehe zu GitHub und erstelle ein Konto

Ein Repository erstellen:

  • Klicke auf "New" (Neu) oben rechts auf der GitHub-Website
  • Gib einen Repository-Namen ein, wähle die Sichtbarkeit (öffentlich oder privat) und füge eine kurze Beschreibung hinzu
  • Klicke auf "Create repository"

Git-Repository clonen:

  • Öffne die Git-Bash (unter Windows) oder das Terminal (unter macOS/Linux)
  • Klone das Repository von GitHub auf deinen lokalen Computer

    git clone <Repository-URL>

Ersetze <Repository-URL> durch die URL des erstellten Repositories, welches auf GitHub zu finden ist.

Dateien hinzufügen und committen:

  • Navigiere in das geklonte Verzeichnis:

    cd <repository-name>

  • Erstelle eine Datei in dem Verzeichnis und füge die Datei dann zur Staging Area hinzu (beispielsweise eine leere README.md Datei).

    git add <datei-name>

  • Commite die Änderungen:

    git commit -m "Mein erster Commit"

Änderungen pushen:

  • Sende deine Commits zum Remote-Repository auf GitHub:

    git push origin <branch-name>

Ersetze <branch-name> durch den Namen deines Branches (z.B. main).

Pull Requests erstellen:

Wenn man an einem Projekt mit anderen arbeitest, können folgendermaßen Pull Requests (PR) erstellt werden, um Änderungen vorzuschlagen:

  • Gehe auf GitHub zu deinem Repository
  • Klicke auf "Pull requests" und dann auf "New pull request"
  • Vergleiche die Änderungen und füge eine Beschreibung hinzu
  • Klicke auf "Create pull request"
  • Nachdem man einen Pull Request erstellt hast kann dieser gemergt werden

GitHub und Projektmanagement

GitHub und ähnliche Plattformen geben Entwicklern auch die Möglichkeit Tickets für Teilaufgaben Projektpläne zu erstellen.

Weiterführende Links

Frontend Development, aber richtig! - Integrierte Entwicklungsumgebungen

IDEs (Integrated Development Environments) sind umfassende Softwareanwendungen, die Entwicklern Werkzeuge zur Verfügung stellen, um Software zu entwickeln, zu debuggen und zu verwalten. Sie bieten eine integrierte Umgebung, die Folgendes umfasst:

Code Editor: Ein Editor für die Erstellung und Bearbeitung von Quellcode in verschiedenen Programmiersprachen mit Funktionen wie Syntaxhervorhebung und Autovervollständigung.

Build Automation: Tools zur Automatisierung von Build-Prozessen, die das Kompilieren von Code und das Erstellen von ausführbaren Anwendungen erleichtern.

Debugger: Ein Debugger, der Entwicklern hilft, Fehler im Code zu identifizieren, zu überprüfen und zu beheben.

Version Control Integration: Integration mit Versionskontrollsystemen wie Git, um Codeänderungen zu verwalten und zu synchronisieren.

Projektmanagement: Funktionen zur Organisation und Verwaltung von Projekten, einschließlich Datei- und Ordnerstrukturen, Abhängigkeitsverwaltung und Projektvorlagen.

Code Refactoring: Werkzeuge zur Optimierung und Umstrukturierung des Codes, um ihn lesbarer, effizienter und wartbarer zu machen.

Plugin-Unterstützung: Die Möglichkeit, Funktionalitäten durch Plugins oder Erweiterungen zu erweitern, die spezielle Anforderungen oder Integrationen bieten können.

Beispiele für populäre IDEs sind:

  • Visual Studio Code (Microsoft, 2024): Eine leichte und leistungsstarke Code-Editor-IDE von Microsoft, die eine Vielzahl von Sprachen und Plattformen unterstützt.
  • IntelliJ IDEA (JetBrains, 2024): Eine Java-IDE von JetBrains, die auch Unterstützung für andere Sprachen bietet und für ihre intelligenten Code-Refactoring-Funktionen bekannt ist.
  • Eclipse (Eclipse Foundation, 2024): Eine plattformübergreifende IDE, die ursprünglich für Java entwickelt wurde, aber durch Plugins erweitert werden kann, um andere Sprachen zu unterstützen.

Diese IDEs erleichtern Entwicklern das Arbeiten, indem sie eine zentrale und effiziente Umgebung bieten, um Code zu schreiben, zu testen und zu verwalten.

Visual Studio Code (VSCode)

Entwickler haben oft Präferenzen, wenn es darum geht, welche IDE am intuitivsten ist. Wir werden die Beispiele anhand von VSCode durchgehen.

Visual Studio Code herunterladen und installieren

Download: Gehe zur VSCode-Website und lade die Installationsdatei für dein Betriebssystem herunter.

Installation:

  • Unter Windows: Öffne die heruntergeladene Datei und folge den Installationsanweisungen
  • Unter MacOS: Ziehe die heruntergeladene VSCode-App in deinen Applications-Ordner.
  • Unter Linux: Installiere VSCode über den Paketmanager deiner Distribution.

Erweiterungen installieren

Man muss sich das Leben nicht zu schwer machen. Es gibt viele nützliche Erweiterungen, die dabei helfen lesbaren, korrekten und effizienten Programmiercode zu schreiben.

Öffne VSCode nach der Installation, um einige nützliche Erweiterungen zu installieren.

Gehe zum "Extensions"-Tab (Symbol auf der linken Seitenleiste) und suche nach den folgenden Erweiterungen:

  • ESLint (OpenJS Foundation, 2024): Ein Linter für JavaScript, der Syntaxfehler und Best Practices prüft.
  • Prettier - Code formatter (Prettier, 2024): Ein Tool zur automatischen Codeformatierung.

Klicke auf "Install", um die Erweiterungen hinzuzufügen.

Hello, World

Erstelle nun einen neuen Ordner auf deinem Computer, um deine JavaScript-Datei zu speichern. Zum Beispiel: hello-world-js.

  • Öffne VS Code
  • Gehe zu Datei > Ordner öffnen.. und wähle das zuvor erstellte Verzeichnis hello-world-js aus
  • Klicke im Explorer-Fenster von VS Code (links) auf das Symbol Neue Datei.
  • Nenne die Datei index.html
  • Füge den folgenden HTML-Code in die index.html Datei ein
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <metaname="viewport"content="width=device-width, initial-scale=1.0">
      <title>Hello World</title>
   </head>
   <body>
      <h1>Hello World</h1>
      <script>
         // JavaScript Code
         console.log('Hello, World!');
      </script>
   </body>
</html>
  • Speichere die index.html Datei (Strg+S oder Datei > Speichern)
  • Navigiere zu deinem Projektverzeichnis und öffne die index.html Datei mit einem Webbrowser (z.B. Chrome, Firefox, Safari)
  • Öffne die Entwicklerwerkzeuge des Browsers. In Chrome und Firefox kann man dies mit der rechten Maustaste auf der Seite tun und dann auf „Untersuchen“ oder „Element untersuchen“klicken
  • Gehe zum Tab „Konsole”

„Hello, World!“ sollte in der Konsole zu sehen sein

Datei:Media/image1.png

Datei:Media/image2.png

Weiterführende Links

Fallbeispiel: From Peer Review to Crowd Review

Wir werden die Frontend Development und JavaScript Konzepte anhand eines Fallbeispiels durchgehen. Dieses Beispiel wird sich durch den gesamten Kurs ziehen und die Konzepte werden daran veranschaulicht.

Der Peer-Review-Prozess ist entscheidend für die Qualitätssicherung wissenschaftlicher Publikationen. Autoren reichen Manuskripte bei Zeitschriften ein, wo es zunächst von Editoren geprüft wird. Wenn es thematisch und formal passt, wird es an Experten (Gutachter) weitergeleitet. Diese bewerten die Arbeit hinsichtlich ihrer methodischen Korrektheit, Bedeutung, Originalität und Klarheit und erstellen Gutachten mit Empfehlungen zur Akzeptanz, Überarbeitung oder Ablehnung. Die Autoren erhält Feedback, überarbeiten das Manuskript gegebenenfalls und reichen es erneut ein. Nach mehreren Runden von Überarbeitungen und Begutachtungen treffen die Editoren eine endgültige Entscheidung, und die Arbeit wird veröffentlicht. Dieser Prozess ist doppel-blind oder doppel-anonym. Dies bedeutet, dass sowohl die Autoren als auch die Gutachter anonym bleiben. Weder die Autoren wissen, wer die Gutachter sind, noch wissen die Gutachter, wer die Autoren sind. Dies soll sicherstellen, dass die Bewertung der Arbeit objektiv und frei von Vorurteilen erfolgt.

Dieser Prozess hat mehrere Probleme. Gutachter können unbewusst voreingenommen sein, was zu unfairen Bewertungen führt. Die Anonymität der Begutachtungen kann Verantwortlichkeit verringern und Interessenkonflikte verschleiern. Der Prozess ist oft zeitaufwendig, was die Veröffentlichung verzögert, und die Qualität der Gutachten kann stark variieren. Gutachter sind häufig überlastet, was die Schnelligkeit und Qualität der Begutachtungen beeinträchtigten kann. Zudem besteht ein Publikationsbias zugunsten positiver Ergebnisse, und die hohen Kosten traditioneller Zeitschriften schränken den Zugang zu Forschungsergebnissen ein.

Ein Beispiel, welches ich gerne zur Veranschaulichung bringe, ist der Fall von drei MIT-Studenten, die 2015 erfolgreich gefälschte Forschungspapiere bei wissenschaftlichen Zeitschriften einreichten. Diese Papiere, die methodische Fehler und wissenschaftlich unsinnige Inhalte enthielten, wurden von den Gutachtern akzeptiert. Lest euch das Beispiel durch: https://news.mit.edu/2015/how-three-mit-students-fooled-scientific-journals-0414

Stellen wir uns also folgende Anwendung vor: Ein webbasiertes System zur transparenten Veröffentlichung, Begutachtung und Diskussion wissenschaftlicher Publikationen. Sie bietet eine Plattform, auf der Autoren ihre Forschungsarbeiten einreichen, Gutachter diese begutachten und Leser über die veröffentlichten Arbeiten diskutieren können. Der Prozess ist durch verschiedene Rollen (Autor, Gutachter, Leser) und klare Workflow-Schritte strukturiert.

In so einem System könnte man sich folgendes Datenmodell vorstellen:

Benutzer: Enthält alle Benutzer des Systems und speichert deren Informationen wie Benutzername, E-Mail, Passwort (gehasht) und Rolle (Autor, Gutachter, Leser) ab.

Publikationen: Speichert Informationen zu den wissenschaftlichen Publikationen wie Titel, Abstract, Inhalt, Autor und den aktuellen Status der Veröffentlichung ab.

Gutachten: Enthält die Gutachten, die von Gutachtern verfasst wurden, und Empfehlung (Akzeptieren, Kleine Überarbeitung, Große Überarbeitung, Ablehnen).

Kommentare: Ermöglicht Diskussionen und Kommentare zu den Publikationen durch verschiedene Benutzer.

GutachterZuweisungen: Verknüpft Gutachter mit den Publikationen, die sie bewerten sollen.

Wir werden in diesem Studienheft Schritt für Schritt die Benutzeroberfläche einer solcher Anwendung erstellen und optimieren.

Modernes Frontend Development

Beim Start eines Frontend-Projekts beginnt man mit dem Einrichten der Entwicklungsumgebung. Visual Studio Code wird installiert und konfiguriert, um eine effiziente Programmierumgebung zu bieten. Ein GitHub-Repository wird erstellt, um Versionskontrolle zu nutzen, und auf den lokalen Rechner geklont. Das Projekt wird in VSCode geöffnet und es werden hilfreiche Erweiterungen installiert.

Der nächste Schritt ist die Planung der Benutzeroberfläche. Wireframes und Mockups werden erstellt, um die Hauptbildschirme der Anwendung zu skizzieren, wie die Startseite, Publikationsübersicht und Detailansichten. Design-Tools wie Figma (Figma, 2024) werden verwendet, um die Benutzeroberflächen und deren Interaktionen detailliert zu entwerfen.

Für die Application Programming Interface (API)-Definition (auf Deutsch Programmierschnittstelle) werden die benötigten Endpunkte festgelegt, die zur Kommunikation mit dem Server genutzt werden. Eine API-Spezifikation kann beispielsweise mit OpenAPI (OpenAPI, 2024) erstellt werden, die die Endpunkte, Parameter und Rückgabewerte beschreibt. Diese Spezifikation wird in Tools wie Swagger UI (Swagger, 2024) geladen, um eine interaktive Dokumentation zu erstellen und die API zu testen.

Abschließend wird ein Frontend-Framework ausgewählt, das den Anforderungen entspricht. Beliebte Optionen wie React (Meta Open Source, 2024), Angular (Google, 2024) oder Vue.js (You, 2024) bieten umfassende Funktionalitäten zur Unterstützung der Anwendung. Das gewählte Framework wird eingerichtet, indem ein neues Projekt erstellt und konfiguriert wird, um die Entwicklungsarbeit zu beginnen.

JavaScript wird oft geschätzt, weil es vielseitig und zentral für die Webentwicklung ist, mit vielen nützlichen Bibliotheken und ständiger Weiterentwicklung. Die Sprache wird jedoch auch kritisiert wegen seiner Inkonsistenzen, untypisierten Natur und Sicherheitsproblemen, sowie wegen der Komplexität der zahlreichen Frameworks und Tools.

HTML5, CSS3 und JavaScript arbeiten zusammen, um moderne Webseiten zu gestalten. HTML5 definiert die grundlegende Struktur und den Inhalt der Webseite. CSS3 kümmert sich um das visuelle Design und Layout, wie Farben, Schriftarten und Abstände. JavaScript ermöglicht interaktive und dynamische Funktionen, indem es auf Benutzeraktionen reagiert und Inhalte in Echtzeit aktualisiert. Zusammen bieten diese Technologien die Basis für ansprechende und funktionale Webanwendungen.

Dies wäre kein vollständiges Frontend Development Studienheft ohne die Erwähnung von TypeScript (Microsoft, 2024). Wir werden uns auf JavaScript konzentrieren, in der Praxis wird jedoch oft TypeScript anstelle von JavaScript verwendet. Einer der größten Kritikpunkte von JavaScript ist, wie oben erwähnt, die untypisierte Natur. Ein kurzer Ausflug: In untypisierten Sprachen wie JavaScript können Variablen Werte unterschiedlichen Typs annehmen, und Typprüfungen erfolgen erst zur Laufzeit. Das bedeutet, dass Variablen flexibel sind, aber Typfehler erst beim Ausführen des Programms entdeckt werden können. In typisierten Sprachen wie TypeScript, Java oder C#, müssen Typen bereits zur Entwicklungszeit festgelegt werden, was eine frühzeitige Fehlererkennung und strukturierteren Code ermöglicht. Diese Sprachen überprüfen die Typen entweder zur Kompilierzeit oder bei der Programmausführung, was zu robusterem und weniger fehleranfälligem Code führt. Weitere untypisierte Sprachen sind Python, Ruby, PHP und Perl.

TypeScript ist eine Erweiterung von JavaScript, die statische Typisierung bietet, wodurch viele Fehler bereits zur Entwicklungszeit erkannt werden können. JavaScript ist flexibler und wird direkt von Browsern ausgeführt, erfordert jedoch Laufzeitprüfungen für Typfehler. TypeScript bietet zusätzliche Funktionen und eine robustere Entwicklungsumgebung, während JavaScript aufgrund seiner Flexibilität und breiten Unterstützung bevorzugt wird.

HTML, HTML5 für die Strukturierung von Webseiten

HTML (Hypertext Markup Language) und HTML5 sind beide Markup-Sprachen zur Strukturierung von Webseiten. HTML5 bringt einige Verbesserungen gegenüber HTML mit sich.

HTML ist die grundlegende Sprache für die Erstellung von Webseiten und definiert, wie Inhalte wie Texte, Links, Bilder und Listen strukturiert werden. Es bietet grundlegende Elemente, die es ermöglichen, einfache und funktionale Webseiten zu erstellen.

Elemente sind beispielsweise:

  • <h1> bis <h6> für Überschriften
  • <p> für Absätze
  • <a> für Hyperlinks
  • <img> für Bilder

HTML5 ist die neuere Version von HTML und baut auf HTML auf. Es bietet neue semantische Tags wie <header>, <footer>, <section>, und <article>, die helfen, Webseiten besser zu strukturieren und den Inhalt klarer zu gliedern. HTML5 unterstützt auch erweiterte Multimedia-Elemente wie <video> und <audio>, die es einfacher machen, Medieninhalte ohne zusätzliche Plugins einzubinden. Zudem bringt es Verbesserungen bei der Formularverarbeitung und der Unterstützung für moderne Webanwendungen, einschließlich APIs für lokale Speicherung und grafische Darstellungen.

Heutzutage ist HTML5 der Standard für die Webentwicklung.

Viel genützte Tags sind:

  • <header>: Definiert den Kopfbereich einer Seite oder eines Abschnitts
  • <nav>: Navigationslinks
  • <section>: Markiert thematische Abschnitte innerhalb des Dokuments
  • <article>: Stellt eigenständige Inhalte dar, die unabhängig wiederverwendet werden können
  • <footer>: Gibt den Fußbereich einer Seite oder eines Abschnitts an
  • <aside>: Definiert Inhalte, die nicht direkt zum Hauptinhalt gehören (z.B. Seitenleisten)
  • <main>: Markiert den Hauptinhalt der Seite
  • <figure> und <figcaption>: Dienen zur Darstellung von Bildern und zugehörigen Beschreibungen
  • <video>: Einbetten von Videos
  • <audio>: Einbetten von Audiodateien
  • <progress>: Zeigt den Fortschritt eines laufenden Prozesses an.

In unserem Beispiel von oben haben wir einige dieser Tags verwendet. Nun fügen wir etwas CSS5 hinzu.

 CSS, CSS3 für das Styling von Webseiten

CSS (Cascading Style Sheets) ist die grundlegende Styling-Sprache für Webseiten. CSS3 ist die aktuelle Version, die erweiterte Funktionen für modernes Layout und Design bietet.

CSS-Konstrukte

Selektoren: Bestimmen, welche HTML-Elemente gestaltet werden. Beispiel: p für alle Absätze, .class für Elemente mit der Klasse „class“, #id für das Element mit der ID „id“

Eigenschaften: Definieren, welche Stile angewendet werden. Beispiel: „color“ für die Textfarbe, „font-size“ für die Schriftgröße

Werte: Geben die spezifischen Einstellungen für die Eigenschaften an. Beispiel: „color: red“; für rote Textfarbe, „font-size: 16px;“ für eine Schriftgröße von 16 Pixel

Box-Modell: Beschreibt das Layout von Elementen.

Beispiele:

  • „margin: 10px“, für den äußeren Abstand
  • „border: 1px solid black“ für einen schwarzen Rand, padding: 5px; für den inneren Abstand, width: 100px; für die Breite des Inhaltsbereichs

Positionierung: Bestimmt, wie Elemente auf der Seite angeordnet werden. Beispiel: “position: relative;“ für relative Positionierung, „position: absolute;“ für absolute Positionierung, „top: 10px; left: 20px;“ für die Platzierung des Elements.

CSS3 führt eine Reihe neuer Konstrukte und Module ein, die das Design und Layout von Webseiten erweitern:

Flexbox: Ein Layout-Modul für flexible und anpassungsfähige Layouts. Beispiel: display: flex; auf einem Container, um dessen Kinder flexibel zu gestalten.

Grid Layout: Ermöglicht komplexe, zweidimensionale Layouts mit Zeilen und Spalten. Beispiel: display: grid;für ein Gitter-Layout.

Media Queries: Passen das Design je nach Bildschirmgröße oder Gerätetyp an. Beispiel: @media (max-width: 600px) { /* Styles für kleine Bildschirme */ }.

Animationen und Übergänge: Erlauben das Erstellen von dynamischen Effekten. Beispiel: @keyframes für Animationen und transition: all 0.3s ease; für sanfte Übergänge zwischen Zuständen.

Transform: Ermöglicht das Skalieren, Drehen oder Verschieben von Elementen. Beispiel: transform: rotate(45deg); zum Drehen eines Elements.

Gradienten: Erstellen von Farbverläufen. Beispiel: background: linear-gradient(to right, red, yellow);für einen Verlauf von Rot nach Gelb.

Hier das oben erwähnte Beispiel etwas aufgehübscht. Öffnen wir das Beispiel nun wieder in einem Browser und sehen es uns an.<ppre>

<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>From Peer Review to Crowd Review</title>
<style>
  body {
    font-family: Arial, sans-serif;
    background: linear-gradient(to right, #342fc9, #2da327);
    color: #333;
    text-align: center;
    margin: 0;
    padding: 0;
  }

  h1 {

    color: #007bff;
    font-size: 3em;
    margin-top: 20vh;
    transition: color 0.3s ease;
  }

  h1:hover {

    color: #0056b3;
    transform: scale(1.1);
  }
</style>
</head>
<body>
<h1> From Peer Review to Crowd Review </h1>

<script>

// JavaScript Code
console.log('Hello World!');
</script>

</body>

</html>
  • CSS3 wurde im <style>-Tag hinzugefügt
  • Der Hintergrund der Seite verwendet einen linearen Farbverlauf.
  • Der Text der Überschrift <h1> erhält eine Farbe und eine Schriftgröße, und eine Übergangsanimation wird hinzugefügt, die beim Hover-Effekt die Farbe ändert und den Text leicht vergrößert.

Datei:Media/image3.png

JavaScript-Syntax, Variablen, Datentypen und Operatoren

Sehen wir uns nun die einzelnen Konstrukte der Sprache JavaScript genauer an.

Variablen

Deklaration: Variablen sind Container zum Speichern von Datenwerten. In JavaScript können sie mit den Schlüsselwörtern var, let und const deklariert werden.

  • var: Wird verwendet, um eine Variable mit Funktions-Scope zu deklarieren. Variablen, die mit var deklariert wurden, können innerhalb ihrer Funktion neu deklariert und aktualisiert werden.
  • let: Wird verwendet, um eine Variable mit Block-Scope zu deklarieren. Variablen, die mit let deklariert wurden, können innerhalb ihres Blocks aktualisiert, aber nicht neu deklariert werden.
  • const: Wird verwendet, um eine Konstante zu deklarieren, die nicht neu zugewiesen werden kann. Konstanten haben ebenfalls Block-Scope.

Beispiele:

var alterBenutzername = 'neo_the_one';

let benutzername = 'alice_wonderland';

const email = 'alice@example.com';

let rolle = 'Autor';

Datentypen

Primitive Typen: Dazu gehören Number, String, Boolean, Null, Undefined und Symbol.

Komplexe Typen: Dazu gehören Objekte und Arrays.

Beispiele für primitive Typen sind:

Number:

let zahl = 42;

String:

let text = "Hello World";

Boolean:

let wahrOderFalsch = true;

Null:

let leererWert = null;

Undefined:

let undefiniert;

Symbol:

let symbol = Symbol("einzigartig");

Operatoren

Vergleichsoperatoren: Werden verwendet, um zwei Werte zu vergleichen. Die gängigen Vergleichsoperatoren sind ==, ===, !=, !==, <, >, <=, >=.

Gleich (==): Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 == '42'ergibt true, weil '5' zu 5 konvertiert wird.

Strikte Gleichheit (===): Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen denselben Typ und Wert haben. Beispiel: 42 === '42' ergibt false, da die Typen unterschiedlich sind.

Ungleich (!=): Vergleicht zwei Werte, wobei Typkonvertierungen durchgeführt werden, wenn nötig. Beispiel: 42 != '42'ergibt false, da '42' zu 42 konvertiert wird.

Strikte Ungleichheit (!==): Vergleicht zwei Werte ohne Typkonvertierungen. Beide Werte müssen entweder im Typ oder im Wert unterschiedlich sein. Beispiel: 42 !== '42' ergibt true, da die Typen unterschiedlich sind.

Größer als (>): Überprüft, ob der linke Wert größer als der rechte Wert ist. Beispiel: 42 > 23 ergibt true.

Kleiner als (<): Überprüft, ob der linke Wert kleiner als der rechte Wert ist. Beispiel: 23 < 42 ergibt true.

Größer oder gleich (>=): Überprüft, ob der linke Wert größer oder gleich dem rechten Wert ist. Beispiel: 42 >= 42 ergibt true, und 42 >= 23 ergibt true.

Kleiner oder gleich (<=): Überprüft, ob der linke Wert kleiner oder gleich dem rechten Wert ist. Beispiel: 23 <= 42 ergibt true, und 42 <= 42 ergibt true.

In unserem Fallbeispiel könnten wir Operatoren beispielsweise folgendermaßen verwenden:

if (publikation.status === 'eingereicht') {
   console.log('Die Publikation wurde eingereicht und wartet auf Begutachtung.');
}

Funktionen

Funktion: Ein Block von Code, der entworfen wurde, um eine bestimmte Aufgabe auszuführen. Funktionen können Parameter (Eingaben) annehmen und ein Ergebnis zurückgeben.

function neuerBenutzer(benutzername, email, passwort, rolle) {
return {
benutzername: benutzername,
email: email,
passwort: passwort,
rolle: rolle
};

} let neuerAutor = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password2', 'Autor');

Kontrollstrukturen

Bedingte Anweisungen: Dazu gehören if, else if und else, die verwendet werden, um Code basierend auf spezifischen Bedingungen auszuführen.

Schleifen: Dazu gehören for, while und do...while, die verwendet werden, um Codeblöcke wiederholt auszuführen.

if (neuerAutor.rolle === 'Autor') {

console.log('Willkommen, Autor!');

}

let gutachtenListe = [

{ empfehlung: 'Akzeptieren', kommentar: 'Sehr gute Arbeit.' },

{ empfehlung: 'Kleine Überarbeitung', kommentar: 'Einige kleine Korrekturen erforderlich.' }

];

for (let i = 0; i < gutachtenListe.length; i++) {

console.log(gutachtenListe[i].empfehlung);

}

Objekte und Arrays

Objekte: Sammlungen von Schlüssel-Wert-Paaren, wobei die Schlüssel Zeichenketten oder Symbole und die Werte beliebige Datentypen sein können.

Arrays: Geordnete Listen von Werten, auf die über ihren Index zugegriffen wird.

Beispiel einen Objektes:

let kommentar = {

benutzername: 'neo_the_one',

kommentar: 'Sehr interessante Publikation!',

datum: '2024-08-10'

};

Beispiel eines Arrays:

let wissenschaftlichePublikationen = ["Deep Learning in AI", "Quantum Computing Advances", "Blockchain Technology Overview", "Genomics and CRISPR", "Sustainable Energy Solutions"];

In JavaScript greift man auf einzelne Elemente folgendermaßen zu:

let erstePublikation = wissenschaftlichePublikationen[0];

In diesem Fall ist erstePublikation gleich "Deep Learning in AI".

JavaScript-Arrays sind etwas flexibler als Arrays in anderen Programmiersprachen. Sie sind dynamisch und können wachsen oder schrumpfen, ohne eine feste Größe zu haben. Sie erlauben auch das Speichern von Elementen unterschiedlicher Typen, wie Zahlen, Strings und Objekte. Das macht sie flexibler im Vergleich zu Arrays in Sprachen wie Java, die eine feste Größe haben und nur Elemente eines einzigen Datentyps enthalten können. Zudem bieten JavaScript-Arrays zahlreiche eingebaute Methoden zur Manipulation von Daten, wie push, pop und shift, was sie vielseitiger und einfacher zu handhaben macht.

Ereignisse

Ereignis: Eine Aktion welche im System erkannt und darauf reagiert wird. Beispiele sind Mausklicks, Tastatureingaben oder das Laden einer Seite.

Mausklick:

document.getElementById("zeigePublikation").addEventListener("click", function() {

alert("Publikation: Deep Learning in AI");

});

Mouseover (Maus über ein Element bewegen):

document.getElementById("zeigePublikation").addEventListener("mouseover", function() {

console.log("Maus ist über dem Publikationsbereich!");

});

Keydown (Tastendruck):

document.addEventListener("keydown", function(event) {

console.log("Gedrückte Taste: " + event.key);

});

Seitenladen (DOMContentLoaded):

document.addEventListener("DOMContentLoaded", function() {

console.log("Die Seite ist vollständig geladen!");

});

Formular absenden:

document.getElementById("publikationsFormular").addEventListener("submit", function(event) {

event.preventDefault(); // Verhindert das Standardverhalten

alert("Formular zur Publikation wurde abgesendet!");

});

Fehlerbehandlung

Fehlerbehandlung: Verwendung von try, catch, finally und throw, um Fehler zu erkennen und zu verarbeiten.

try {

let neuerGutachter = neuerBenutzer('alice_wonderland', 'alice@example.com', 'hashed_password3', 'Gutachter');

if (!neuerGutachter.email.includes('@')) {
   throw new Error('Ungültige E-Mail-Adresse');
   } 
} catch (error) {
   console.log(error.message); }

Module

Module: Erlauben es, Code in separate Dateien zu unterteilen. Jedes Modul kann Werte oder Funktionen exportieren und in anderen Dateien importieren.

// benutzer.js

export function neuerBenutzer(benutzername, email, passwort, rolle) {

return {

benutzername: benutzername,

email: email,

passwort: passwort,

rolle: rolle

};

}

// main.js

import { neuerBenutzer } from './benutzer.js';

let neuerLeser = neuerBenutzer('neo_the_one', 'neo@example.com', 'hashed_password4', 'Leser');

console.log(neuerLeser);

DOM, DOM, DOM

Der Document Object Model (DOM) ist eine Programmierschnittstelle für HTML- und XML-Dokumente. Es repräsentiert die Struktur eines Dokuments als eine Baumstruktur, wobei jede HTML- oder XML-Komponente (wie Tags, Attribute und Text) als Knoten dargestellt wird. Mit dem DOM können Sie die Struktur, den Inhalt und das Styling eines Dokuments dynamisch ändern.

Kommen wir zurück zu unserem Fallbeispiel. Auf unserer Webseite möchten wir Informationen zu Publikationen anzeigen und es den Benutzern ermöglichen, Kommentare zu hinterlassen.

Ein einfaches HTML-Dokument für unser System könnte wie folgt aussehen:

<!DOCTYPE html>

<html lang="de"> <head> <meta charset="UTF-8">

<title>Publikationen</title>

</head>

<body>

<h1>Wissenschaftliche Publikationen</h1>
<div id="publikation-container">
<h2 id="publikation-titel">Gibt es die Matrix wirklich?</h2>
<p id="publikation-abstract">Eine umfassende Analyse der Frage, ob wir in einer simulierten Realität leben.</p>
<div id="kommentare">
<h3>Kommentare</h3>
<!-- Kommentare werden hier hinzugefügt -->
</div>
<textarea id="neuer-kommentar" placeholder="Fügen Sie einen Kommentar hinzu..."></textarea>
<button id="kommentar-hinzufuegen">Kommentar hinzufügen</button>
</div>
<script src="app.js"></script>

</body>

</html>


Datei:Media/image4.png

In diesem Beispiel haben wir HTML-Elemente wie h1, h2, p, div, textarea und button, die verschiedene Teile unserer Publikationsseite darstellen. Das DOM repräsentiert diese Elemente als Knoten in einem Baum.

In unserem JavaScript-Code können wir auf diese DOM-Elemente zugreifen und sie manipulieren. Erstelle in demselben Ordner eine neue Datei app.js. In dieser Datei schreiben wir den JavaScript Code. Auf diesen wird in dem obigen Beispiel mit <script src=“app.js“> zugegriffen. Manipulieren wir nun die HTML Datei mit JavaScript code. Hier sind einige Beispiele:

// Zugriff auf DOM-Elemente

let titelElement = document.getElementById('publikation-titel');

let abstractElement = document.getElementById('publikation-abstract');

let kommentareElement = document.getElementById('kommentare');

let textareaElement = document.getElementById('neuer-kommentar');

let buttonElement = document.getElementById('kommentar-hinzufuegen');

// Hinzufügen eines Kommentars

buttonElement.addEventListener('click', () => {

let neuerKommentar = textareaElement.value;

if (neuerKommentar) {

let kommentarElement = document.createElement('p');

kommentarElement.textContent = neuerKommentar;

kommentareElement.appendChild(kommentarElement);

textareaElement.value = ; // Textarea leeren

} else {

alert('Bitte geben Sie einen Kommentar ein.');

}

}); Öffne die HTML Datei erneut in deinem Browser und siehe was sich verändert hat.

Datei:Media/image5.png

Datei:Media/image6.png

Im obigen JavaScript-Beispiel verwenden wir das DOM, um:

  • Elemente zu finden: Wir greifen auf Elemente wie den Titel und das Abstract der Publikation zu.
  • Ereignisse zu behandeln: Wir fügen einen Event-Listener für den Button hinzu, um einen Kommentar hinzuzufügen, wenn der Button geklickt wird.
  • Elemente zu erstellen und zu modifizieren: Wir erstellen neue p-Elemente für Kommentare und fügen sie dem DOM hinzu. Außerdem ändern wir den Inhalt von textarea und leeren ihn nach dem Hinzufügen eines Kommentars.

Die Baumstruktur des DOM für unser Beispiel sieht folgendermaßen aus:

<html>

<head>

<meta>

<title>

<body>

<h1>

<div id="publikation-container">

<h2 id="publikation-titel">

<p id="publikation-abstract">

<div id="kommentare">

<h3>

(Kommentare werden hier hinzugefügt)

<textarea id="neuer-kommentar">

<button id="kommentar-hinzufuegen">


Sehen wir uns nun weitere Beispiele von Ereignissen an.

Ereignis: Eingabe in Textarea

Beschreibung: Zeigt eine Live-Vorschau des eingegebenen Kommentars an, während der Benutzer tippt.

// Zugriff auf DOM-Elemente

let textareaElement = document.getElementById('neuer-kommentar');

let liveVorschauElement = document.createElement('div');

liveVorschauElement.id = 'live-vorschau';

document.body.appendChild(liveVorschauElement);

// Ereignis-Handler für die Eingabe in die Textarea

textareaElement.addEventListener('input', () => {

let eingabeText = textareaElement.value;

liveVorschauElement.textContent = `Vorschau: ${eingabeText}`;

});

Datei:Media/image7.png

Ereignis: Mausbewegung

Beschreibung: Ändert die Hintergrundfarbe eines Elements, wenn die Maus darüber bewegt wird.

// Zugriff auf DOM-Element

let titelElement = document.getElementById('publikation-titel');

// Ereignis-Handler für Mausbewegung

titelElement.addEventListener('mouseover', () => {

titelElement.style.backgroundColor = '#f0f0f0'; // Hintergrundfarbe ändern

});

// Ereignis-Handler für Mausverlassen

titelElement.addEventListener('mouseout', () => {

titelElement.style.backgroundColor = ; // Hintergrundfarbe zurücksetzen

});

Datei:Media/image8.png

Ereignis: Formular-Submit

Beschreibung: Verhindert das Standard-Submit-Verhalten eines Formulars und zeigt stattdessen eine Bestätigungsmeldung an.

index.html

<form id="kommentar-form">

<textarea id="neuer-kommentar" placeholder="Fuegen Sie einen Kommentar hinzu...">

</textarea>

<button type="submit" id="kommentar-hinzufuegen">Kommentar hinzufuegen

</button>

</form>

<script src="app.js"></script>

app.js

// Zugriff auf DOM-Elemente

let textareaElement = document.getElementById('neuer-kommentar');

let formElement = document.getElementById('kommentar-form');

// Ereignis-Handler für Formular-Submit

formElement.addEventListener('submit', (event) => {

event.preventDefault(); // Verhindert das Standard-Submit-Verhalten

let neuerKommentar = textareaElement.value;

if (neuerKommentar) {

let kommentarElement = document.createElement('p');

kommentarElement.textContent = neuerKommentar;

textareaElement.value = ; // Textarea leeren

alert('Kommentar erfolgreich hinzugefuegt!');

} else {

alert('Bitte geben Sie einen Kommentar ein.');

}

});

Datei:Media/image9.png

Datei:Media/image10.png

Ereignis: Tastatureingabe

Beschreibung: Zeigt eine Nachricht an, wenn die Eingabetaste gedrückt wird.

// Ereignis-Handler für Tastatureingaben

document.addEventListener('keydown', (event) => {

if (event.key === 'Enter') {

alert('Eingabetaste wurde gedrückt!');

}

});

Datei:Media/image11.png

Ereignis: Ändern eines Select-Menüs

Beschreibung: Zeigt die ausgewählte Option aus einem Dropdown-Menü an, wenn der Benutzer eine Auswahl trifft.

<select id="rolle-select">

<option value="Autor">Autor</option>

<option value="Gutachter">Gutachter</option>

<option value="Leser">Leser</option>

</select>

<div id="ausgewaehlte-rolle"></div>

// Zugriff auf DOM-Elemente

let rolleSelectElement = document.getElementById('rolle-select');

let ausgewaehlteRolleElement = document.getElementById('ausgewaehlte-rolle');

// Ereignis-Handler für Änderungen des Select-Menüs

rolleSelectElement.addEventListener('change', () => {

let ausgewaehlteRolle = rolleSelectElement.value;

ausgewaehlteRolleElement.textContent = `Ausgewählte Rolle: ${ausgewaehlteRolle}`;

});

Datei:Media/image12.png

Frameworks

JavaScript-Frameworks erleichtern die Webentwicklung, indem sie strukturierte Ansätze, wiederverwendbare Komponenten und integrierte Funktionen bieten. Die meistverwendeten Frameworks sind React (Meta, 2024), Angular (Google, 2024) und Vue.js (You, 2024). React, von Facebook entwickelt, konzentriert sich auf die Erstellung von Benutzeroberflächen mit einem komponentenbasierten Modell und einem Virtual DOM für effiziente Updates. Angular, gepflegt von Google, bietet eine umfassende Lösung für große Webanwendungen, inklusive Dependency Injection und Routing, und verwendet TypeScript für statische Typisierung. Vue.js ist ein leichtgewichtiges Framework, das einfach zu integrieren und zu lernen ist, und bietet eine flexible API, die Elemente von React und Angular kombiniert. Die Wahl eines Frameworks hängt von den spezifischen Projektanforderungen ab. Diese Frameworks sparen Zeit, verbessern die Code-Qualität, optimieren die Leistung und bieten umfassende Dokumentation sowie Community-Support, was zu schnellerer, konsistenterer und wartbarer Entwicklung führt.

React

React ist eine JavaScript-Bibliothek, die es ermöglicht, komplexe Benutzeroberflächen in wiederverwendbare, isolierte Komponenten zu zerlegen. Diese Komponenten verwalten ihren eigenen Zustand und nutzen einen virtuellen DOM, um effizient Änderungen an der Benutzeroberfläche vorzunehmen. Dies führt zu einer reaktiven und schnellen Anwendung.

Komponenten

In React ist eine Komponente ein selbstständiges, wiederverwendbares Stück der Benutzeroberfläche. Sie kann in andere Komponenten eingebettet werden und hat ihren eigenen Zustand und ihre eigene Logik.

Beispiel: Für unsere Anwendung könnten wir eine Publikation-Komponente erstellen, die die Details einer wissenschaftlichen Publikation anzeigt.

function Publikation({ titel, abstract, inhalt }) {

return (

<div>

<h2>{titel}</h2>

<p>{abstract}</p>

<div>{inhalt}</div>

</div>

);

}

In diesem Beispiel ist Publikation eine Komponente, die titel, abstract und inhalt als Props erhält und diese Daten in der Benutzeroberfläche darstellt.

JSX

JSX ist eine Syntaxerweiterung für JavaScript, die es ermöglicht, HTML-ähnlichen Code direkt in JavaScript zu schreiben. Dieser Code wird von React in regulären JavaScript-Code übersetzt.

Beispiel: Das folgende JSX beschreibt die Struktur eines Kommentarformulars.

function KommentarFormular() {

return (

<form>

<textarea placeholder="Fügen Sie einen Kommentar hinzu..." />

<button type="submit">Kommentar hinzufügen</button>

</form>

);

}

Hier sehen wir, wie HTML-ähnlicher Code in JavaScript eingebettet wird, um die Benutzeroberfläche zu definieren.

Props

Props (Eigenschaften) sind Parameter, die an Komponenten übergeben werden, um Daten weiterzugeben. Sie sind unveränderlich innerhalb der Komponente.

Beispiel: In der App-Komponente übergeben wir Daten an die Publikation-Komponente.

function App() {

return (

<Publikation

titel="Gibt es die Matrix wirklich?"

abstract="Eine Untersuchung der Realität und ihrer Möglichkeiten."

inhalt="Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt."

/>

);

}

Hier erhält Publikation die Daten als Props und zeigt diese in der Benutzeroberfläche an.

State

Der State ist der interne Zustand einer Komponente, der sich ändern kann und die Darstellung der Komponente beeinflusst. Er ist veränderbar und ermöglicht es, die Benutzeroberfläche dynamisch zu aktualisieren.

Beispiel: In der KommentarFormular-Komponente verwalten wir den Text des Kommentars im State.

import React, { useState } from 'react';

function KommentarFormular() {

const [kommentar, setKommentar] = useState();

const handleChange = (event) => {

setKommentar(event.target.value);

};

const handleSubmit = (event) => {

event.preventDefault();

alert('Kommentar hinzugefügt: ' + kommentar);

setKommentar();

};

return (

<form onSubmit={handleSubmit}>

<textarea

value={kommentar}

onChange={handleChange}

placeholder="Fügen Sie einen Kommentar hinzu..."

/>

<button type="submit">Kommentar hinzufügen</button>

</form>

);

}

Hier verwenden wir den State, um den aktuellen Kommentar zu speichern und die Benutzeroberfläche bei Änderungen zu aktualisieren.

Lifecycle-Methoden

Lifecycle-Methoden sind spezielle Methoden, die zu verschiedenen Zeitpunkten im Lebenszyklus einer Komponente aufgerufen werden. Bei funktionalen Komponenten werden Hooks verwendet, um ähnliche Funktionalität zu erreichen.

Beispiel: In einer PublikationenListe-Komponente laden wir beim ersten Rendern Daten von einem Server:

import React, { useEffect, useState } from 'react';

function PublikationenListe() {

const [publikationen, setPublikationen] = useState([]);

useEffect(() => {

fetch('/api/publikationen')

.then(response => response.json())

.then(data => setPublikationen(data));

}, []); // Leeres Array bedeutet, dass es nur einmal ausgeführt wird

return (

<div>

{publikationen.map(publikation => (

<Publikation

key={publikation.id}

titel={publikation.titel}

abstract={publikation.abstract}

inhalt={publikation.inhalt}

/>

))}

</div>

);

}

Hier verwenden wir useEffect, um Daten beim ersten Rendern der Komponente abzurufen.

Virtual DOM

Der Virtual DOM ist eine in-memory-Repräsentation des echten DOMs. React verwendet den Virtual DOM, um Änderungen effizienter zu verarbeiten, indem es nur die Teile des echten DOMs aktualisiert, die tatsächlich verändert wurden. Diese Optimierung wird automatisch von React gehandhabt, daher müssen wir keinen speziellen Code dafür schreiben.

Event-Handling

React ermöglicht die Behandlung von Benutzerereignissen wie Klicks und Eingaben direkt innerhalb der JSX-Syntax.

Beispiel: In einer KommentarFormular-Komponente verarbeiten wir das Absenden des Formulars:

function KommentarFormular() {

const [kommentar, setKommentar] = useState();

const handleSubmit = (event) => {

event.preventDefault();

alert('Kommentar hinzugefügt: ' + kommentar);

setKommentar();

};

return (

<form onSubmit={handleSubmit}>

<textarea

value={kommentar}

onChange={(e) => setKommentar(e.target.value)}

placeholder="Fügen Sie einen Kommentar hinzu..."

/>

<button type="submit">Kommentar hinzufügen</button>

</form>

);

}

Hier wird der onSubmit-Event-Handler verwendet, um den Kommentar beim Absenden des Formulars zu verarbeiten.

Hooks

Hooks sind Funktionen, die es ermöglichen, in funktionalen Komponenten auf den State und andere React-Funktionen zuzugreifen.

Beispiel: Mit useState und useEffect können wir Zustand und Nebenwirkungen in funktionalen Komponenten verwalten:

import React, { useState, useEffect } from 'react';

function KommentarFormular() {

const [kommentar, setKommentar] = useState();

useEffect(() => {

console.log('KommentarFormular gerendert');

}, []);

return (

<form>

<textarea

value={kommentar}

onChange={(e) => setKommentar(e.target.value)}

placeholder="Fügen Sie einen Kommentar hinzu..."

/>

<button type="button" onClick={() => alert('Kommentar hinzugefügt: ' + kommentar)}>Kommentar hinzufügen</button>

</form>

);

}

Hier verwenden wir useState, um den Kommentar zu speichern, und useEffect, um einen Effekt nach dem ersten Rendern auszuführen.

Erste React Applikation in VSCode

Da wir nun die wichtigsten Konzepte, die React verwendet, kennengelernt haben, können wir nun unsere erste React App in VSCode ertellen.

Installiere Node.js und npm

Besuche die Node.js-Website und lade die neueste LTS-Version herunter. Dies installiert auch npm, das für das Verwalten von Paketen verwendet wird.

Installiere create-react-app

Öffne dein Terminal oder die Kommandozeile und installiere das create-react-app-Tool global:

npm install -g create-react-app

Erstelle ein neues React-Projekt

Gehen wir in das Verzeichnis, in dem das Projekt erstellt werden soll, und führen wir diesen Befehl aus:

npx create-react-app from-peer-review-to-crowd-review

Dieser Befehl erstellt ein neues Verzeichnis namens fromPeerReviewToCrowdReview mit einer grundlegenden React-Anwendung.

Öffne das Projekt in Visual Studio Code

Starte Visual Studio Code und öffne das Projektverzeichnis. Alternativ kannst man im Terminal folgenden Befehl verwenden:

code from-peer-review-to-crowd-review

Starte den Entwicklungsserver

Öffne das integrierte Terminal in VSCode (Terminal > Neues Terminal) und starte die Entwicklungsumgebung:

npm start

Dies startet den Entwicklungsserver und öffnet deine Anwendung in einem Webbrowser. Der Server überwacht Änderungen an deinem Code und aktualisiert die Anwendung automatisch.

Bearbeite die Anwendung

Gehe zur Datei src/App.js. Ändere den Code, um die Benutzeroberfläche für unsere Anwendung darzustellen:

import React from 'react';

import Publikation from './Publikation'; // Importiere die neue Komponente

function App() {

return (

<div className="App">

<header className="App-header">

<h1>Wissenschaftliche Publikationen</h1>

<Publikation

titel="Gibt es die Matrix wirklich?"

abstract="Eine Untersuchung der Realität und ihrer Möglichkeiten."

inhalt="Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt."

/>

</header>

</div>

);

}

export default App;

Füge eine neue Komponente hinzu

Erstelle eine neue Datei src/Publikation.js für die Publikation-Komponente:

import React from 'react';

function Publikation({ titel, abstract, inhalt }) {

return (

<div>

<h2>{titel}</h2>

<p>{abstract}</p>

<div>{inhalt}</div>

</div>

);

}

export default Publikation;

Füge weitere Komponenten hinzu

Wir können nun weitere Komponenten erstellen, die beispielsweise das Kommentarformular und andere Teile der Anwendung zu integrieren. Zum Beispiel, erstelle src/KommentarFormular.js:

import React, { useState } from 'react';

function KommentarFormular() {

const [kommentar, setKommentar] = useState();

const handleChange = (event) => {

setKommentar(event.target.value);

};

const handleSubmit = (event) => {

event.preventDefault();

alert('Kommentar hinzugefügt: ' + kommentar);

setKommentar();

};

return (

<form onSubmit={handleSubmit}>

<textarea

value={kommentar}

onChange={handleChange}

placeholder="Fügen Sie einen Kommentar hinzu..."

/>

<button type="submit">Kommentar hinzufügen</button>

</form>

);

}

export default KommentarFormular;

Importiere und verwende diese Komponente in App.js.

Angular

Angular ist ein weit verbreitetes Framework für die Entwicklung von Webanwendungen, das von Google entwickelt wird. Es basiert auf TypeScript und bietet eine strukturierte Architektur für den Aufbau von Single-Page-Anwendungen. Angular nutzt Komponenten als grundlegende Bausteine für die Benutzeroberfläche und bietet eine Vielzahl von Funktionen wie Datenbindung, Dependency Injection und Routing, um die Entwicklung und Wartung von komplexen Anwendungen zu erleichtern. Es enthält auch ein leistungsstarkes CLI (Command Line Interface) zum Generieren von Code und zur Verwaltung von Projekten. Angular ist bekannt für seine umfassenden Features und seine robuste Architektur, die es für große und skalierbare Projekte geeignet macht.

Komponenten

In Angular sind Komponenten die Hauptbausteine der Benutzeroberfläche. Jede Komponente besteht aus einer HTML-Vorlage, einer CSS-Datei für das Styling und einer TypeScript-Datei für die Logik.

Beispiel: Erstellen wir eine PublikationComponent, um eine Publikation anzuzeigen.

HTML-Datei (publikation.component.html):

<div>

<h2>Vorlage:Titel</h2>

<p>Vorlage:Abstract</p>

<div>Vorlage:Inhalt</div>

</div>

TypeScript-Datei (publikation.component.ts):

import { Component, Input } from '@angular/core';

@Component({

selector: 'app-publikation',

templateUrl: './publikation.component.html',

styleUrls: ['./publikation.component.css']

})

export class PublikationComponent {

@Input() titel: string;

@Input() abstract: string;

@Input() inhalt: string;

}

Module

Angular-Anwendungen bestehen aus Modulen, die verschiedene Teile der Anwendung gruppieren. Ein Modul kann Komponenten, Dienste und andere Module enthalten.

Beispiel: Definieren wir ein Modul für die Publikationsfunktionalität.

TypeScript-Datei (app.module.ts):

import { NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { PublikationComponent } from './publikation/publikation.component';

@NgModule({

declarations: [

AppComponent,

PublikationComponent

],

imports: [

BrowserModule

],

providers: [],

bootstrap: [AppComponent]

})

export class AppModule { }

Services

Services sind wiederverwendbare Klassen, die Logik und Datenmanagement bereitstellen. Sie werden oft verwendet, um Daten zwischen Komponenten zu teilen.

Beispiel: Erstellen wir nun einen PublikationService, um Publikationen von einer API abzurufen.

TypeScript-Datei (publikation.service.ts):

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';

@Injectable({

providedIn: 'root'

})

export class PublikationService {

private apiUrl = 'https://api.example.com/publikationen';

constructor(private http: HttpClient) { }

getPublikationen(): Observable<any[]> {

return this.http.get<any[]>(this.apiUrl);

}

}

Routing

Angular-Routing ermöglicht das Navigieren zwischen verschiedenen Ansichten oder Komponenten innerhalb einer Anwendung.

Beispiel: Konfigurieren wir Routen für die Publikationsansicht und ein Kommentarformular.

TypeScript-Datei (app-routing.module.ts):

import { NgModule } from '@angular/core';

import { RouterModule, Routes } from '@angular/router';

import { PublikationComponent } from './publikation/publikation.component';

const routes: Routes = [

{ path: 'publikationen', component: PublikationComponent },

{ path: , redirectTo: '/publikationen', pathMatch: 'full' }

];

@NgModule({

imports: [RouterModule.forRoot(routes)],

exports: [RouterModule]

})

export class AppRoutingModule { }

Datenbindung

Angular bietet verschiedene Arten der Datenbindung, einschließlich Einweg- und Zweiweg-Datenbindung, um Daten zwischen der Logik der Komponente und der Ansicht zu synchronisieren.

Beispiel: Zeigen wir nun Daten aus dem PublikationService in der PublikationComponent an.

TypeScript-Datei (publikation.component.ts):

import { Component, OnInit } from '@angular/core';

import { PublikationService } from '../publikation.service';

@Component({

selector: 'app-publikation',

templateUrl: './publikation.component.html',

styleUrls: ['./publikation.component.css']

})

export class PublikationComponent implements OnInit {

publikationen: any[] = [];

constructor(private publikationService: PublikationService) { }

ngOnInit(): void {

this.publikationService.getPublikationen().subscribe(data => {

this.publikationen = data;

});

}

}

Forms

Angular bietet sowohl Template-driven Forms als auch Reactive Forms für die Verarbeitung von Benutzereingaben.

Beispiel: Erstellen wir ein Formular zum Hinzufügen von Kommentaren.

HTML-Datei (kommentar-formular.component.html):

<form (ngSubmit)="onSubmit()" #kommentarForm="ngForm">

<textarea

name="kommentar"

[(ngModel)]="kommentar"

placeholder="Fügen Sie einen Kommentar hinzu..."

required>

</textarea>

<button type="submit">Kommentar hinzufügen</button>

</form>

TypeScript-Datei (kommentar-formular.component.ts):

import { Component } from '@angular/core';

@Component({

selector: 'app-kommentar-formular',

templateUrl: './kommentar-formular.component.html',

styleUrls: ['./kommentar-formular.component.css']

})

export class KommentarFormularComponent {

kommentar: string = ;

onSubmit(): void {

alert('Kommentar hinzugefügt: ' + this.kommentar);

this.kommentar = ;

}

}

Dependency Injection

Angular verwendet Dependency Injection (DI), um Abhängigkeiten wie Services in Komponenten und andere Services einzufügen.

Beispiel: Der PublikationService wird in PublikationComponent durch DI eingefügt.

TypeScript-Datei (publikation.component.ts):

import { Component, OnInit } from '@angular/core';

import { PublikationService } from '../publikation.service';

@Component({

selector: 'app-publikation',

templateUrl: './publikation.component.html',

styleUrls: ['./publikation.component.css']

})

export class PublikationComponent implements OnInit {

publikationen: any[] = [];

constructor(private publikationService: PublikationService) { }

ngOnInit(): void {

this.publikationService.getPublikationen().subscribe(data => {

this.publikationen = data;

});

}

}

Mein erstes Angular Projekt in VSCode

Stellen wir zuerst sicher, dass Node.js auf deinem System installiert ist. Node.js kann von der Node.js-Website heruntergeladen und installieren werden.

Installiere Angular CLI global, um ein neues Angular-Projekt zu erstellen:

npm install -g @angular/cli

Erstelle ein neues Angular-Projekt

Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll.

Führe den folgenden Befehl aus, um ein neues Angular-Projekt zu erstellen:

ng new from-peer-review-to-crowd-review

Wähle "Ja" um Angular Routing zu verwenden und verwende das Standard-Stilformat (z. B. CSS).

Öffne das Projekt in Visual Studio Code

Starte Visual Studio Code und öffne das Projektverzeichnis:

code from-peer-review-to-crowd-review

Erstelle eine Komponente für die Publikation

Erstelle eine neue Komponente für die Publikationen:

ng generate component publication

HTML-Datei (src/app/publikation/publikation.component.html):

<div>

<h2>Vorlage:Titel</h2>

<p>Vorlage:Abstract</p>

<div>Vorlage:Inhalt</div>

</div>

TypeScript-Datei (src/app/publikation/publikation.component.ts):

import { Component, Input } from '@angular/core';

@Component({

selector: 'app-publikation',

templateUrl: './publikation.component.html',

styleUrls: ['./publikation.component.css']

})

export class PublikationComponent {

@Input() titel: string;

@Input() abstract: string;

@Input() inhalt: string;

}

Erstelle eine Komponente für das Kommentarformular

Erstelle eine neue Komponente für das Kommentarformular:

ng generate component kommentar-formular

HTML-Datei (src/app/kommentar-formular/kommentar-formular.component.html):

<form (ngSubmit)="onSubmit()" #kommentarForm="ngForm">

<textarea

name="kommentar"

[(ngModel)]="kommentar"

placeholder="Fügen Sie einen Kommentar hinzu..."

required>

</textarea>

<button type="submit">Kommentar hinzufügen</button>

</form>

TypeScript-Datei (src/app/kommentar-formular/kommentar-formular.component.ts):

import { Component } from '@angular/core';

@Component({

selector: 'app-kommentar-formular',

templateUrl: './kommentar-formular.component.html',

styleUrls: ['./kommentar-formular.component.css']

})

export class KommentarFormularComponent {

kommentar: string = ;

onSubmit(): void {

alert('Kommentar hinzugefügt: ' + this.kommentar);

this.kommentar = ;

}

}

Füge Routing hinzu

TypeScript-Datei (src/app/app-routing.module.ts):

import { NgModule } from '@angular/core';

import { RouterModule, Routes } from '@angular/router';

import { PublikationComponent } from './publikation/publikation.component';

import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';

const routes: Routes = [

{ path: 'publikationen', component: PublikationComponent },

{ path: , redirectTo: '/publikationen', pathMatch: 'full' }

];

@NgModule({

imports: [RouterModule.forRoot(routes)],

exports: [RouterModule]

})

export class AppRoutingModule { }

TypeScript-Datei (src/app/app.module.ts): Füge die neuen Komponenten und das FormsModule hinzu:

import { NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';

import { FormsModule } from '@angular/forms'; // Importiere FormsModule

import { AppComponent } from './app.component';

import { PublikationComponent } from './publikation/publikation.component';

import { KommentarFormularComponent } from './kommentar-formular/kommentar-formular.component';

import { AppRoutingModule } from './app-routing.module';

@NgModule({

declarations: [

AppComponent,

PublikationComponent,

KommentarFormularComponent

],

imports: [

BrowserModule,

AppRoutingModule,

FormsModule // Füge FormsModule hinzu

],

providers: [],

bootstrap: [AppComponent]

})

export class AppModule { }

Starte die Anwendung

Starte den Angular-Entwicklungsserver, um deine Anwendung auszuführen:

ng serve

Öffne einen Webbrowser und gehe zu http://localhost:4200, um die Anwendung zu sehen.

Verändere die app.component.html

HTML-Datei (src/app/app.component.html): Ersetze den Standardinhalt, um die PublikationComponent und KommentarFormularComponent einzuschließen:

<div class="app">

<h1>Wissenschaftliche Publikationen</h1>

<app-publikation

titel="Gibt es die Matrix wirklich?"

abstract="Eine Untersuchung der Realität und ihrer Möglichkeiten."

inhalt="Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.">

</app-publikation>

<app-kommentar-formular></app-kommentar-formular>

</div>

Nun haben wir eine grundlegende Angular-Anwendung erstellt, die eine Publikation anzeigt und ein Kommentarformular enthält. Diese Anwendung verwendet grundlegende Angular-Konzepte wie Komponenten, Module, Routing und Formulare.

Vue.js

Vue.js ist besonders für seine Einfachheit und Flexibilität bekannt. Vue.js verwendet eine deklarative Syntax, bei der die Benutzeroberfläche mit einem reaktiven Datenmodell verknüpft ist, was bedeutet, dass sich die UI automatisch aktualisiert, wenn sich die zugrunde liegenden Daten ändern. Es basiert auf Komponenten, die HTML, CSS und JavaScript in einer einzigen Datei kombinieren, was die Entwicklung und Wartung von Anwendungen erleichtert. Vue.js ist leichtgewichtig, leicht erlernbar und lässt sich gut in bestehende Projekte integrieren oder für die Entwicklung von neuen, komplexeren Anwendungen nutzen.

Komponenten

In Vue.js sind Komponenten wiederverwendbare und isolierte Einheiten, die HTML, CSS und JavaScript zusammenfassen.

Beispiel: Erstellen wir eine Publikation-Komponente, um eine Publikation darzustellen.

Datei Publikation.vue:

<template>

<div>

<h2>Vorlage:Titel</h2>

<p>Vorlage:Abstract</p>

<div>Vorlage:Inhalt</div>

</div>

</template>

<script>

export default {

props: {

titel: String,

abstract: String,

inhalt: String

}

}

</script>

<style scoped>

/* Styles für die Publikation */

</style>

Reaktive Datenbindung

Vue.js verwendet reaktive Datenbindung, um sicherzustellen, dass Änderungen an Daten automatisch in der Benutzeroberfläche angezeigt werden.

Beispiel: Verwenden wir eine data-Eigenschaft in einer App-Komponente, um eine Liste von Publikationen zu verwalten.

Datei App.vue:

<template>

<div id="app">

<h1>Wissenschaftliche Publikationen</h1>

<Publikation

v-for="(publikation, index) in publikationen"

key="index"
titel="publikation.titel"
abstract="publikation.abstract"
inhalt="publikation.inhalt"

/>

<KommentarFormular />

</div>

</template>

<script>

import Publikation from './components/Publikation.vue';

import KommentarFormular from './components/KommentarFormular.vue';

export default {

components: {

Publikation,

KommentarFormular

},

data() {

return {

publikationen: [

{

titel: 'Gibt es die Matrix wirklich?',

abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',

inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'

}

]

}

}

}

</script>

<style>

/* Styles für die App */

</style>

Props

Props sind Eigenschaften, die von einer übergeordneten Komponente an eine untergeordnete Komponente übergeben werden, um Daten zu übermitteln.

Beispiel: Die Publikation-Komponente erhält titel, abstract und inhalt als Props.

In Publikation.vue:

<template>

<div>

<h2>Vorlage:Titel</h2>

<p>Vorlage:Abstract</p>

<div>Vorlage:Inhalt</div>

</div>

</template>

<script>

export default {

props: {

titel: String,

abstract: String,

inhalt: String

}

}

</script>

Event Handling

Vue.js ermöglicht es, Benutzeraktionen wie Klicks und Eingaben zu erfassen und darauf zu reagieren.

Beispiel: Erstellen wir nun ein Kommentarformular, das einen Kommentar hinzufügt und anzeigt.

Datei KommentarFormular.vue:

<template>

<form @submit.prevent="onSubmit">

<textarea v-model="kommentar" placeholder="Fügen Sie einen Kommentar hinzu..." required></textarea>

<button type="submit">Kommentar hinzufügen</button>

</form>

</template>

<script>

export default {

data() {

return {

kommentar:

}

},

methods: {

onSubmit() {

alert('Kommentar hinzugefügt: ' + this.kommentar);

this.kommentar = ;

}

}

}

</script>

<style scoped>

/* Styles für das Kommentarformular */

</style>

Vue Router

Vue Router ist eine offizielle Router-Bibliothek für Vue.js, die das Routing innerhalb der Anwendung ermöglicht.

Beispiel: Konfigurieren wir nun Routen, um zwischen verschiedenen Komponenten zu navigieren.

Datei router/index.js:

import Vue from 'vue';

import Router from 'vue-router';

import Publikation from '../components/Publikation.vue';

import KommentarFormular from '../components/KommentarFormular.vue';

Vue.use(Router);

export default new Router({

routes: [

{

path: '/publikationen',

name: 'Publikation',

component: Publikation

},

{

path: '/',

name: 'KommentarFormular',

component: KommentarFormular

}

]

});

In der Hauptdatei main.js:

import Vue from 'vue';

import App from './App.vue';

import router from './router';

Vue.config.productionTip = false;

new Vue({

router,

render: h => h(App)

}).$mount('#app');

Vuex

Vuex ist eine State-Management-Bibliothek für Vue.js-Anwendungen, die ein zentrales Repository für alle Komponenten bereitstellt.

Beispiel: Verwende Vuex für die Verwaltung der Publikationen.

Datei store/index.js:

import Vue from 'vue';

import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({

state: {

publikationen: [

{

titel: 'Gibt es die Matrix wirklich?',

abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',

inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'

}

]

},

mutations: {

addPublikation(state, publikationen) {

state.publikationen.push(publikationen);

}

},

actions: {

addPublikation({ commit }, publikationen) {

commit('addPublikation', publikationen);

}

}

});

In App.vue:

<template>

<div id="app">

<h1>Wissenschaftliche Publikationen</h1>

<Publikation

v-for="(publikation, index) in $store.state.publikationen"

key="index"
titel="publikation.titel"
abstract="publikation.abstract"
inhalt="publikation.inhalt"

/>

<KommentarFormular />

</div>

</template>

Mit diesen Konzepten kann man strukturierte Vue.js-Anwendung erstellen, die eine Publikation anzeigt und ein Kommentarformular enthält.

Mein erstes Vue.js Projekt in VSCode

Es beginnt wieder damit sicherzustellen, dass Node.js auf deinem System installiert ist. Falls nicht, lade es von der Node.js-Website herunter und installiere es.

Installiere Vue CLI global, um ein neues Vue-Projekt zu erstellen:

npm install -g @vue/cli

Erstelle ein neues Vue-Projekt

Öffne das Terminal oder die Kommandozeile und navigiere zu dem Verzeichnis, in dem das Projekt erstellt werden soll. Führe den folgenden Befehl aus:

vue create from-peer-review-to-crowd-review

Wähle die Standardkonfiguration oder passe sie nach Bedarf an.

Öffne das Projekt in Visual Studio Code

Starte Visual Studio Code und öffne das neu erstellte Projektverzeichnis:

code from-peer-review-to-crowd-review

4. Erstelle Komponenten

Erstelle eine neue Datei für die Publikation-Komponente:

  • Erstelle einen neuen Ordner components im src-Verzeichnis
  • Füge eine Datei Publikation.vue im src/components-Ordner hinzu

Datei src/components/Publikation.vue:

<template>

<div>

<h2>Vorlage:Titel</h2>

<p>Vorlage:Abstract</p>

<div>Vorlage:Inhalt</div>

</div>

</template>

<script>

export default {

props: {

titel: String,

abstract: String,

inhalt: String

}

}

</script>

<style scoped>

/* Styles für die Publikation */

</style>

Füge eine Datei KommentarFormular.vue im src/components-Ordner hinzu.

Datei src/components/KommentarFormular.vue:

<template>

<form @submit.prevent="onSubmit">

<textarea v-model="kommentar" placeholder="Fügen Sie einen Kommentar hinzu..." required></textarea>

<button type="submit">Kommentar hinzufügen</button>

</form>

</template>

<script>

export default {

data() {

return {

kommentar:

}

},

methods: {

onSubmit() {

alert('Kommentar hinzugefügt: ' + this.kommentar);

this.kommentar = ;

}

}

}

</script>

<style scoped>

/* Styles für das Kommentarformular */

</style>

Konfiguriere Routing

Falls das Projekt noch keinen Router enthält, installiere Vue Router:

npm install vue-router

Erstelle eine Datei router/index.js im src-Verzeichnis:

Datei src/router/index.js:

import Vue from 'vue';

import Router from 'vue-router';

import Publikation from '../components/Publikation.vue';

import KommentarFormular from '../components/KommentarFormular.vue';

Vue.use(Router);

export default new Router({

routes: [

{

path: '/publikationen',

name: 'Publikation',

component: Publikation

},

{

path: '/',

name: 'KommentarFormular',

component: KommentarFormular

}

]

});

Verwende die Komponenten in App.vue

Ersetze den Inhalt der App.vue, um die Publikation- und KommentarFormular-Komponenten einzuschließen:

Datei src/App.vue:

<template>

<div id="app">

<h1>Wissenschaftliche Publikationen</h1>

<Publikation

v-for="(publikation, index) in publikationen"

key="index"
titel="publikation.titel"
abstract="publikation.abstract"
inhalt="publikation.inhalt"

/>

<KommentarFormular />

</div>

</template>

<script>

import Publikation from './components/Publikation.vue';

import KommentarFormular from './components/KommentarFormular.vue';

export default {

components: {

Publikation,

KommentarFormular

},

data() {

return {

publikationen: [

{

titel: 'Gibt es die Matrix wirklich?',

abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',

inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'

}

]

}

}

}

</script>

<style>

/* Styles für die App */

</style>

Starte die Anwendung

Starte den Vue-Entwicklungsserver, um die Anwendung auszuführen:

npm run serve

Öffne einen Webbrowser und gehe zu http://localhost:8080, um die Anwendung zu sehen.

Jetzt haben wir ein funktionierendes Vue.js-Projekt erstellt, welches eine Publikation anzeigt und ein Kommentarformular enthält.

Asynchrone Programmierung und Datenübertragung

Frontend-Entwicklung konzentriert sich auf die Gestaltung der Benutzeroberfläche und Interaktivität einer Webanwendung unter Verwendung moderner Technologien wie HTML5, CSS3 und JavaScript-Frameworks wie React, Angular oder Vue.js. Im Full-Stack-Kontext arbeitet das Frontend mit dem Backend zusammen, das durch Technologien wie Node.js, Express und Datenbanken wie MongoDB oder PostgreSQL unterstützt wird. Die Kommunikation zwischen Frontend und Backend erfolgt typischerweise durch RESTful APIs oder GraphQL, wobei JSON oder XML als Formate für den Datenaustausch verwendet werden. Promises und async/await sind Methoden zur Handhabung von asynchronem Code in JavaScript. Sie helfen dabei, Code lesbarer und wartbarer zu machen, insbesondere wenn man mit asynchronen Operationen wie API-Anfragen oder Datenverarbeitung arbeitet.

Sehen wir uns nun an, wie man Promises und async/await in unserem Beispiel anwenden kann. Promises sind Objekte, die einen zukünftigen Wert repräsentieren. Sie bieten eine Möglichkeit, asynchrone Operationen zu verwalten, indem sie auf den Abschluss dieser Operation warten.

Angenommen, wir möchten die Publikationen von einem Server abrufen. Wir verwenden eine Funktion, die ein Promise zurückgibt:

JavaScript Code:

// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)

function fetchPublikationen() {

return new Promise((resolve, reject) => {

setTimeout(() => {

const publikationen = [

{

titel: 'Gibt es die Matrix wirklich?',

abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',

inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'

}

];

resolve(publikationen);

}, 1000);

});

}

// Nutzung des Promises

fetchPublikationen().then(publikationen => {

console.log('Publikationen erhalten:', publikationen);

}).catch(error => {

console.error('Fehler beim Abrufen der Publikationen:', error);

});

In diesem Beispiel simulieren wir die asynchrone Abrufoperation mit setTimeout. Die Funktion fetchPublikationen gibt ein Promise zurück, das nach einer Verzögerung von 1 Sekunde die Publikationen auflöst (resolve). Wenn ein Fehler auftritt, wird die Funktion reject aufgerufen.

async/await

async/await ist eine syntaktische Vereinfachung für die Arbeit mit Promises, die es ermöglicht, asynchrone Operationen wie synchronen Code zu schreiben.

Wir können das gleiche Beispiel mit async/await umsetzen:

JavaScript Code:

// Funktion zum Abrufen von Publikationen (simuliert mit setTimeout)

function fetchPublikationen() {

return new Promise((resolve, reject) => {

setTimeout(() => {

const publikationen = [

{

titel: 'Gibt es die Matrix wirklich?',

abstract: 'Eine Untersuchung der Realität und ihrer Möglichkeiten.',

inhalt: 'Hier wird die Forschung zu den Fragen der Matrix-Theorie vorgestellt.'

}

];

resolve(publikationen);

}, 1000);

});

}

// Async-Funktion zum Abrufen und Anzeigen von Publikationen

async function showPublikationen() {

try {

const publikationen = await fetchPublikationen();

console.log('Publikationen erhalten:', publikationen);

} catch (error) {

console.error('Fehler beim Abrufen der Publikationen:', error);

}

}

// Aufruf der async-Funktion

showPublikationen();

Dieses Beispiel erläutert:

  • fetchPublikationen bleibt unverändert und gibt ein Promise zurück
  • showPublikationen ist eine async Funktion. Innerhalb dieser Funktion verwenden wir await, um auf das Ergebnis von fetchPublikationen zu warten. Await pausiert die Ausführung der Funktion, bis das Promise aufgelöst wird.
  • Fehler werden mit try/catch behandelt, was den Code sauber und verständlich macht

Daten zwischen dem Backend und dem Frontend können in mehreren Formaten gesendet werden, meistens wird entweder XML oder JSON verwendet. XML (eXtensible Markup Language) ist ein markiertes Datenformat, das Daten in einer hierarchischen Struktur mit benutzerdefinierten Tags darstellt. Es ist sehr flexibel und kann komplexe Datenstrukturen repräsentieren, wird jedoch als schwerfälliger und aufwändiger in der Verarbeitung angesehen. JSON (JavaScript Object Notation) ist ein leichteres Format, das Daten in einer einfacheren Schlüssel-Wert-Paar-Struktur organisiert. JSON ist leichter lesbar und einfacher zu verarbeiten, insbesondere in JavaScript-Umgebungen. In der Praxis wird JSON häufiger verwendet als XML, da es einfacher zu integrieren und effizienter in modernen Webanwendungen ist. JSON lässt sich nahtlos mit JavaScript kombinieren und ermöglicht eine schnellere und unkompliziertere Datenverarbeitung.

AJAX (Asynchronous JavaScript and XML) ermöglicht die asynchrone Kommunikation zwischen dem Browser und dem Server, wodurch Inhalte dynamisch aktualisiert werden können, ohne die ganze Seite neu zu laden. In unserem Beispiel für eine Plattform zur Veröffentlichung wissenschaftlicher Publikationen können wir AJAX verwenden, um Publikationen vom Server abzurufen und auf der Webseite anzuzeigen. Obwohl der Name "AJAX" XML impliziert, wird in der Praxis oft JSON verwendet.

Beispiel einer XML-Datei:

<publikation>

<titel> Die Matrix: Leben wir in einer Simulation?</titel>

<autor>Alice</autor>

<jahr>2024</jahr>

</publikation>

Und hier dieselbe Information als JSON-Datei:

{

"titel":"Die Matrix: Leben wir in einer Simulation?",

"autor": "Alice",

"jahr": 2024

}

Senden wir nun eine Anfrage mit der fetch-API. Der Server liefert die Publikationen im JSON-Format zurück. Diese Daten werden dann verarbeitet und in der Benutzeroberfläche angezeigt, ohne dass die Seite neu geladen wird.

async function fetchPublikationen() {

try {

const response = await fetch('https://api.example.com/publikationen');

if (!response.ok) {

throw new Error('Netzwerkantwort war nicht okay.');

}

const data = await response.json();

console.log('Publikationen erhalten:', data);

displayPublikationen(data);

} catch (error) {

console.error('Fehler beim Abrufen der Publikationen:', error);

}

}

function displayPublikationen(publikationen) {

const container = document.getElementById('publikationen-container');

container.innerHTML = publikationen.map(p => `

<div>

<h2>${p.titel}</h2>

<p>${p.autor}</p>

<div>${p.jahr}</div>

</div>

`).join();

}

fetchPublikationen();

In diesem Code wird eine Anfrage an die API gesendet, um Publikationen zu erhalten. Die JSON-Daten werden dann verarbeitet und die Inhalte auf der Webseite angezeigt, was eine dynamische und reaktive Benutzererfahrung ermöglicht. Es ist üblich Beispiel-Serverantworten und -anfragen lokal zu speichern und diese Daten (üblicherweise in der Praxis oft JSON-Dateien) im Frontend zu verwenden, also die Daten anhand von diesen JSON Dateien anzuzeigen.

API Definitionen

API-Definitionen sind von zentraler Bedeutung für die Erstellung klarer und konsistenter Schnittstellen, die den Datenaustausch zwischen verschiedenen Systemen regeln. Sie bieten eine strukturierte Übersicht über verfügbare Endpunkte, erforderliche Parameter und die Formate der zurückgegebenen Daten, was die Integration von Frontend und Backend vereinfacht. OpenAPI (The Linux Foundation, 2024), ehemals bekannt als Swagger, ist ein weit verbreitetes Tool zur Definition und Dokumentation von APIs. Mit OpenAPI können Entwickler präzise API-Spezifikationen in einem maschinenlesbaren Format erstellen, das auch interaktive Dokumentation umfasst. Diese Dokumentation erleichtert es Entwicklern, die API zu verstehen und zu testen, ohne direkt mit dem Backend-Code interagieren zu müssen. OpenAPI unterstützt die klare Kommunikation der API-Funktionalitäten und trägt zur Konsistenz und Interoperabilität bei der Systemintegration bei.

Um die OpenAPI-Spezifikation für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen visuell anzusehen und zu testen, können wir die Swagger UI verwenden. Hier ist eine Schritt-für-Schritt-Anleitung, wie dies aussehen kann:

Swagger UI verwenden

Swagger UI lokal einrichten:

  • Lade die Swagger UI herunter oder klone das Repository
  • Öffne das Verzeichnis dist und kopiere die Dateien swagger-ui-bundle.js, swagger-ui-standalone-preset.js und swagger-ui.css in ein Verzeichnis, das von deinem Webserver bereitgestellt wird

OpenAPI-Spezifikation einbinden:

Erstelle eine HTML-Datei, zum Beispiel index.html, im selben Verzeichnis wie die Swagger UI Dateien und binde die OpenAPI-Spezifikation ein. Die index.html könnte folgendermaßen aussehen:

<!DOCTYPE html>

<html lang="en"> <head> <meta charset="UTF-8"> <title>Swagger UI</title>

<link rel="stylesheet" type="text/css" href="swagger-ui.css" >

<script src="swagger-ui-bundle.js" charset="UTF-8"> </script> <script src="swagger-ui-standalone-preset.js" charset="UTF-8"> </script>

<script> window.onload = function() { const ui = SwaggerUIBundle({ url: "path/to/your/openapi.yaml", // Pfad zu deiner OpenAPI-Spezifikation dom_id: '#swagger-ui', presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset], layout: "StandaloneLayout" });

window.ui = ui;

}

</script> </head> <body> <div id="swagger-ui"></div> </body> </html>


Ersetze path/to/your/openapi.yaml durch den Pfad zu deiner OpenAPI-Spezifikation.

Swagger UI lokal öffnen:

Starte einen lokalen Webserver, um die index.html Datei anzuzeigen. Zum Beispiel kannst man dies mit Python tun: python -m http.server im Verzeichnis mit der index.html Datei.

Öffne deinen Browser und navigiere zu der URL, die deinem lokalen Webserver zugewiesen ist, wie http://localhost:8000, um die interaktive API-Dokumentation deiner Publikationen-Plattform zu sehen.

API Definition für unser Fallbeispiel

In unserem Beispiel könnte man sich folgende vereinfachte API Definitionen vorstellen:

POST /register

POST /login

POST /publications

GET /publications/{id}

POST /reviews

GET /comments?publicationId={id}

POST erstellt neue Daten auf dem Server. PUT aktualisiert bestehende Daten. GET ruft Daten vom Server ab, ohne sie zu ändern. Im Frontend Development ist sollte man immer die gesamte Applikation verstehen und wie die Daten am effizientesten zwischen dem Server und dem Frontend ausgetauscht werden können. Deshalb ist es wichtig sich die API-Definition, sowie das UI-Design, am Anfang eines neuen Frontendprojekts gut zu überlegen. Die API-Definition ist der Vertrag zwischen der UI und dem Server. Sehen wir uns nun die Datenübertragung für ein paar Endpunkte im Detail an.

  1. POST /register

Beschreibung: Registriert einen neuen Benutzer im System.

Anfrage:

{

"username": "alice",

"email": "alice@example.com",

"password": "securepassword",

"role": "Author"

}

Antwort:

{

"id": 1,

"username": "alice",

"email": "alice@example.com",

"role": "Author"

}

  1. POST /login

Beschreibung: Authentifiziert einen Benutzer und erstellt eine Sitzung.

Anfrage:

{

"email": "alice@example.com",

"password": "securepassword"

}

Antwort:

{

"token": "jwt-token-string"

}

  1. POST /publications

Beschreibung:Erstellt eine neue wissenschaftliche Publikation.

Anfrage:

{

"title": "Einfluss von KI auf Peer-Review-Prozesse",

"abstract": "Diese Arbeit untersucht...",

"content": "Der komplette Inhalt...",

"authorId": 1

}

Antwort:

{

"id": 101,

"title": "Einfluss von KI auf Peer-Review-Prozesse",

"status": "Eingereicht"

}

  1. GET /publications/{id}

Beschreibung: Gibt Details zu einer spezifischen Publikation zurück. Parameter:

  • id (Pfadparameter): Die ID der Publikation.

Antwort:

{

"id": 101,

"title": "Einfluss von KI auf Peer-Review-Prozesse",

"abstract": "Diese Arbeit untersucht...",

"content": "Der komplette Inhalt...",

"status": "Eingereicht",

"authorId": 1

}

  1. POST /reviews

Beschreibung: Ein Gutachter erstellt ein Gutachten für eine Publikation.

Anfrage:

{

"publicationId": 101,

"reviewerId": 2,

"comments": "Die Arbeit ist gut, aber...",

"recommendation": "Kleine Überarbeitung"

}

Antwort:

{

"id": 201,

"publicationId": 101,

"reviewerId": 2,

"status": "Gutachten erstellt"

}

  1. GET /comments?publicationId={id}

Beschreibung: Listet alle Kommentare zu einer Publikation auf. Parameter:

  • publicationId (Query-Parameter): Die ID der Publikation.

Antwort:

[

{

"id": 301,

"publicationId": 101,

"userId": 3,

"content": "Sehr interessante Ergebnisse!"

},

{

"id": 302,

"publicationId": 101,

"userId": 4,

"content": "Ich stimme dem Gutachter zu, aber..."

}

]

Alternative Tools

Es gibt auch online Tools zur API-Dokumentation. Beispielsweise:

  • Swagger Editor (SmartBear, 2024): Besuche Swagger Editor, lade eine OpenAPI-Spezifikation hoch oder füge den Inhalt direkt ein, um die API-Dokumentation zu erstellen und zu testen.
  • Postman (Postman, Inc., 2024): Lade eine OpenAPI-Spezifikation in Postman, um die API-Dokumentation anzuzeigen und API-Anfragen zu testen.

Diese Tools helfen, die API-Dokumentation für die Plattform zu visualisieren und zu überprüfen, wie die API funktioniert.

Responsive Webdesign

Responsive Webdesign sorgt dafür, dass Websites auf allen Geräten gut aussehen, indem sie sich automatisch an verschiedene Bildschirmgrößen anpassen. Zu den Prinzipien gehören flexible Layouts, die sich an unterschiedliche Bildschirmgrößen anpassen, skalierbare Bilder und Schriften sowie die Verwendung von Media Queries in CSS, um spezifische Stile für verschiedene Geräte zu definieren. Ziel ist es, eine konsistente und nutzerfreundliche Erfahrung auf Smartphones, Tablets und Desktops zu bieten.

Gestaltung von Benutzeroberflächen, die auf verschiedenen Geräten und Bildschirmgrößen gut funktionieren

Sehen wir uns ein paar HTML und CSS-Konzepte an, die es ermöglichen Elemente unterschiedlich auf unterschiedlichen Geräten darzustellen. Die besprochenen JavaScript Frameworks helfen auch dabei Websites zu designen die sowohl auf großen Bildschirmen als auch auf Smartphones gut bedienbar sind.

Responsive Layout

Verwende Flexbox für ein flexibles Layout, das sich an verschiedene Bildschirmgrößen anpasst.

<!-- HTML-Struktur -->

<div class="publikationen-container">

<div class="publikation">

<h2>Publikation 1</h2>

<p>Abstract...</p>

</div>

<div class="publikation">

<h2>Publikation 2</h2>

<p>Abstract...</p>

</div>

<!-- Weitere Publikationen -->

</div>

/* CSS für responsives Layout */

.publikationen-container {

display: flex;

flex-wrap: wrap;

gap: 16px;

}

.publikation {

flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout mit Abstand */

box-sizing: border-box;

}

@media (max-width: 768px) {

.publikation {

flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout auf Tablets */

}

}

@media (max-width: 480px) {

.publikation {

flex: 1 1 100%; /* Einspaltiges Layout auf Mobilgeräten */

}

}

Media Queries

Passe Stile für unterschiedliche Bildschirmgrößen an, um das Layout und die Schriftgröße zu optimieren.

/* Media Queries für unterschiedliche Bildschirmgrößen */

@media (max-width: 1200px) {

.header {

font-size: 1.5em;

}

}

@media (max-width: 768px) {

.header {

font-size: 1.2em;

}

.navigation {

display: none; /* Navigation auf kleineren Bildschirmen ausblenden */

}

}

Flexible Bilder

Stelle sicher, dass Bilder sich proportional zur Bildschirmgröße skalieren.

/* Flexibles Bild */

img {

max-width: 100%;

height: auto;

}

Touchfreundliche Elemente

Gestalte Schaltflächen und Links groß genug für eine einfache Bedienung auf Touchscreens.

/* Touchfreundliche Schaltflächen */

button {

padding: 12px 20px;

font-size: 16px;

}

Testen

Nutze Entwicklertools in Browsern oder echte Geräte, um das Layout und die Funktionalität auf verschiedenen Bildschirmgrößen zu überprüfen. Mit diesen Techniken und Beispielen kannst man sicherstellen, dass unsere Plattform für wissenschaftliche Publikationen auf allen Geräten gut aussieht und benutzerfreundlich ist.

Medienabfragen und die Verwendung von CSS-Frameworks zur Unterstützung des responsiven Designs

Medienabfragen

Medienabfragen ermöglichen es, CSS-Stile basierend auf den Eigenschaften des Geräts wie Bildschirmgröße und -auflösung anzupassen. Sie sind besonders nützlich, um sicherzustellen, dass deine Plattform auf verschiedenen Bildschirmgrößen gut aussieht.

Beispiel: Wir möchten das Layout der Publikationen auf unterschiedlichen Geräten anpassen.

/* Standardlayout für große Bildschirme */

.publikationen-container {

display: flex;

flex-wrap: wrap;

gap: 16px;

}

.publikation {

flex: 1 1 calc(33.333% - 32px); /* Drei Spalten Layout für große Bildschirme */

box-sizing: border-box;

}

/* Layout für Tablets */

@media (max-width: 768px) {

.publikation {

flex: 1 1 calc(50% - 32px); /* Zwei Spalten Layout für Tablets */

}

}

/* Layout für Mobilgeräte */

@media (max-width: 480px) {

.publikation {

flex: 1 1 100%; /* Einspaltiges Layout für Mobilgeräte */

}

}

Verwendung von CSS-Frameworks

CSS-Frameworks bieten vorgefertigte Klassen und Komponenten, die helfen, responsives Design schnell und einfach zu implementieren. Beliebte Frameworks sind Bootstrap, Foundation und Tailwind CSS.

Bootstrap ist ein weit verbreitetes CSS-Framework, das eine Reihe von nützlichen Klassen für responsives Design bereitstellt. Füge die Bootstrap CSS-Datei in deinem HTML-Dokument ein.

<!-- Bootstrap CSS einbinden -->

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

Verwende Bootstrap-Klassen, um ein responsives Layout für deine Publikationen zu erstellen.

<!-- HTML-Struktur mit Bootstrap-Klassen -->

<div class="container">

<div class="row">

<div class="col-md-4 mb-4">

<div class="card">

<div class="card-body">

<h5 class="card-title">Publikation 1</h5>

<p class="card-text">Abstract...</p>

</div>

</div>

</div>

<div class="col-md-4 mb-4">

<div class="card">

<div class="card-body">

<h5 class="card-title">Publikation 2</h5>

<p class="card-text">Abstract...</p>

</div>

</div>

</div>

<!-- Weitere Publikationen -->

</div>

</div>

In diesem Beispiel verwendet die Plattform Bootstrap-Klassen wie container, row und col-md-4, um ein responsives Raster zu erstellen, das sich je nach Bildschirmgröße anpasst. Bootstrap sorgt dafür, dass das Layout auf großen Bildschirmen in drei Spalten und auf kleineren Bildschirmen in einer oder zwei Spalten angezeigt wird. Durch die Kombination von Medienabfragen und CSS-Frameworks kann man sicherstellen, dass deine Plattform zur Veröffentlichung wissenschaftlicher Publikationen auf verschiedenen Geräten gut aussieht und benutzerfreundlich ist.

Leistungsoptimierung

Niemand wartet gerne mehrere Sekunden, bis eine Website vollständig geladen ist. Jede Website, die wir entwickeln sollte, immer so optimiert wie möglich sein. Performance-Benchmarks messen, wie schnell und gut eine Website läuft. Sie helfen dabei, die Benutzererfahrung zu verbessern. Es ist ratsam die Performance einer Website immer wieder zu messen, um sicherzugehen dass man Ladezeiten mit neuen Grafiken oder anderen Elementen unnötig verlängert hat.

Optimierung von Ladezeiten

Szenario: Die Seite lädt eine Liste von Publikationen, einschließlich Titel, Abstract und Inhaltszusammenfassung.

Wir haben folgende Optimierungsmöglichkeiten:

Lazy Loading: Lade Inhalte nur dann, wenn sie tatsächlich benötigt werden. Anstatt alle Publikationen auf einmal zu laden, zeige zunächst nur eine Übersicht an und lade detaillierte Informationen erst, wenn der Benutzer mehr darüber erfahren möchte. Dies reduziert die anfängliche Ladezeit erheblich.

Caching: Verwende Browser-Caching oder serverseitiges Caching, um häufig abgerufene Daten zwischenzuspeichern. Wenn eine Publikation einmal abgerufen wurde, speichere diese Daten lokal oder auf dem Server, um sie bei zukünftigen Anfragen schneller bereitstellen zu können. Dies vermindert die Notwendigkeit, dieselben Daten wiederholt vom Server abzurufen.

Minimierung von HTTP-Anfragen: Reduziere die Anzahl der HTTP-Anfragen durch das Zusammenfassen von CSS- und JavaScript-Dateien. Anstatt mehrere Dateien zu laden, kombiniere sie in einer einzigen Datei, um die Anzahl der Anfragen zu minimieren und die Ladezeit zu verkürzen.

Komprimierung: Komprimiere die Daten, die zwischen Server und Client ausgetauscht werden. Verwende Gzip oder Brotli-Komprimierung, um die Größe der übertragenen Daten zu reduzieren. Dies verringert die Menge an Daten, die heruntergeladen werden müssen, und beschleunigt die Ladezeiten.

Optimierung von Bildern: Stelle sicher, dass alle Bilder auf der Website komprimiert und in einem Web-freundlichen Format vorliegen. Verwende Formate wie WebP oder JPEG 2000, die eine bessere Komprimierung bieten, um die Größe der Bilddateien zu reduzieren und die Ladezeiten zu verbessern.

Content Delivery Network (CDN): Nutze ein CDN, um statische Dateien wie Bilder, CSS und JavaScript von Servern in der Nähe des Benutzers zu liefern. Ein CDN kann die Ladezeiten durch geografische Verteilung und schnelle Bereitstellung von Inhalten verbessern.

Lazy Loading

Lade Publikationen nur bei Bedarf, nicht alle auf einmal. Hier wird zunächst nur eine Übersicht oder ein Teaser angezeigt, und detaillierte Informationen werden erst geladen, wenn der Benutzer auf „Mehr lesen“ klickt oder scrollt.

// Funktion zum Laden der Details einer Publikation auf Knopfdruck

async function loadPublikationDetails(publikationId) {

try {

const response = await fetch(`https://api.example.com/publikationen/${publikationId}`);

if (!response.ok) {

throw new Error('Netzwerkantwort war nicht okay.');

}

const data = await response.json();

displayPublikationDetails(data);

} catch (error) {

console.error('Fehler beim Abrufen der Publikation:', error);

}

}

// Event-Handler für "Mehr lesen" Button

document.querySelectorAll('.more-info').forEach(button => {

button.addEventListener('click', () => {

const publikationId = button.getAttribute('data-id');

loadPublikationDetails(publikationId);

});

});

Caching

Nutze Browser-Caching, um die Daten von Publikationen zwischenzuspeichern. Bei wiederholten Anfragen können die gecachten Daten verwendet werden, anstatt sie erneut vom Server abzurufen.

// Funktion zum Abrufen der Publikationen mit Caching

async function fetchPublikationen() {

const cacheKey = 'publikationen-cache';

const cachedData = localStorage.getItem(cacheKey);

if (cachedData) {

return JSON.parse(cachedData); // Rückgabe der gecachten Daten

}

try {

const response = await fetch('https://api.example.com/publikationen');

if (!response.ok) {

throw new Error('Netzwerkantwort war nicht okay.');

}

const data = await response.json();

localStorage.setItem(cacheKey, JSON.stringify(data)); // Speichern in lokalem Speicher

return data;

} catch (error) {

console.error('Fehler beim Abrufen der Publikationen:', error);

}

}

Minimierung von HTTP-Anfragen

Kombiniere mehrere CSS- und JavaScript-Dateien zu einer einzigen Datei, um die Anzahl der HTTP-Anfragen zu reduzieren.

<!-- Kombinierte CSS-Datei -->

<link rel="stylesheet" href="styles.min.css">

<!-- Kombinierte JavaScript-Datei -->

<script src="scripts.min.js"></script>

Verwende Build-Tools wie Webpack oder Gulp, um deine CSS- und JavaScript-Dateien zu bündeln und zu minimieren.

Komprimierung

Aktiviere Gzip-Komprimierung auf deinem Webserver, um die Größe der übertragenen Daten zu reduzieren.

Beispielsweise kann man dies in der Apache-Konfiguration folgendermaßen machen:

<IfModule mod_deflate.c>

AddOutputFilterByType DEFLATE text/text

AddOutputFilterByType DEFLATE text/html

AddOutputFilterByType DEFLATE text/xml

AddOutputFilterByType DEFLATE text/css

AddOutputFilterByType DEFLATE application/xml

AddOutputFilterByType DEFLATE application/xhtml+xml

AddOutputFilterByType DEFLATE application/rss+xml

AddOutputFilterByType DEFLATE application/javascript

AddOutputFilterByType DEFLATE application/x-javascript

</IfModule>

Optimierung von Bildern

Verwende komprimierte Bildformate wie WebP, um die Größe der Bilddateien zu reduzieren.

<!-- WebP-Bild verwenden -->

<img src="publikationen-image.webp" alt="Publikationsbild">

Content Delivery Network (CDN)

Nutze ein CDN, um statische Dateien wie Bilder und JavaScript von Servern näher am Benutzer bereitzustellen.

<!-- Bild von einem CDN laden -->

<img src="https://cdn.example.com/images/publikationen-image.jpg" alt="Publikationsbild">

Durch diese Optimierungen kann man die Ladezeiten deiner Plattform erheblich verbessern und somit die Benutzererfahrung steigern.

Ressourcenoptimierung

Um den Ressourcenverbrauch in einer Webanwendung zu optimieren, kann man verschiedene Techniken anwenden, um die Effizienz der Nutzung von CPU, Speicher und Netzwerkbandbreite zu verbessern. Hier sind einige Beispiele, wie man dies für unsere Plattform zur Veröffentlichung wissenschaftlicher Publikationen umsetzen kann:

Code-Splitting

Unterteile deinen JavaScript-Code in kleinere, nach Bedarf ladbare Teile. Das reduziert die anfängliche Ladezeit und verbessert die Leistung, da nur der benötigte Code geladen wird.

// Beispiel mit Webpack für Code-Splitting

import(/* webpackChunkName: "publikation-details" */ './publikation-details.js')

.then(module => {

const loadDetails = module.loadDetails;

loadDetails();

})

.catch(err => {

console.error('Fehler beim Laden des Moduls:', err);

});

Vermeidung von übermäßigem DOM-Manipulationen

Reduziere die Anzahl der DOM-Manipulationen, indem man Änderungen in einem Dokumentfragment vornimmt und das Fragment dann einmal in das DOM einfügt.

// Reduziere DOM-Manipulationen

const fragment = document.createDocumentFragment();

const list = document.createElement('ul');

for (let i = 0; i < 100; i++) {

const item = document.createElement('li');

item.textContent = `Publikation ${i + 1}`;

list.appendChild(item);

}

fragment.appendChild(list);

document.getElementById('publikationen-container').appendChild(fragment);

Minimierung von Berechnungen im Haupt-Thread

Verschiebe rechenintensive Aufgaben in Web Worker, um den Haupt-Thread zu entlasten und die Benutzeroberfläche reaktionsfähig zu halten.

// Haupt-Thread

const worker = new Worker('worker.js');

worker.postMessage('start');

// worker.js

self.onmessage = function(event) {

if (event.data === 'start') {

// Rechenintensive Aufgabe

let result = performHeavyComputation();

self.postMessage(result);

}

};

Ressourcenoptimierung durch Lazy Loading von Bildern

Lade Bilder nur dann, wenn sie in den Sichtbereich des Benutzers kommen, um Bandbreite zu sparen und die Ladezeiten zu verbessern.

<!-- Verwende `loading="lazy"` für Lazy Loading von Bildern -->

<img src="image.jpg" loading="lazy" alt="Publikationsbild">

Vermeidung von Redundanz bei Netzwerkanfragen

Nutze ETags und Last-Modified Header zur Validierung von Cache-Inhalten, um unnötige Netzwerkanfragen zu vermeiden.

// Beispiel für einen Server-Response mit ETag

HTTP/1.1 200 OK

ETag: "123456789"

Content-Type: application/json

// Client-seitige Validierung

fetch('https://api.example.com/publikationen', {

headers: {

'If-None-Match': '123456789' // Verwende den ETag-Wert

}

})

.then(response => {

if (response.status === 304) {

console.log('Daten nicht geändert, verwende Cache.');

} else {

return response.json();

}

});

Effiziente Datenabfragen

Wir können API-Anfragen optimieren, indem man nur die benötigten Daten abfragt und die Abfragen entsprechend filtert.

// API-Anfrage mit spezifischen Abfrageparametern

fetch('https://api.example.com/publikationen?fields=titel,abstract')

.then(response => response.json())

.then(data => {

console.log(data);

});

Optimierung der Bildgröße

Verwende Bildkomprimierung und -optimierung, um die Dateigröße zu reduzieren, ohne die Bildqualität merklich zu beeinträchtigen.

 <!-- Komprimiertes Bild verwenden -->
<img src="publikationen-image-compressed.jpg" alt="Publikationsbild">

Durch diese Techniken kann man den Ressourcenverbrauch deiner Anwendung senken, die Leistung verbessern und eine flüssigere Benutzererfahrung bieten.

Bibliography

BitBucket. (2024, Juli 28). BitBucket. Retrieved from BitBucket: https://bitbucket.org

CoPilot, G. (2024, July 10). Retrieved from https://github.com/features/copilot

Eclipse Foundation. (2024, Juli 2024). Eclipse. Retrieved from Eclipse: https://www.eclipse.org

Figma. (2024, Juli 28). Figma. Retrieved from Figma: https://www.figma.com

git. (2024, Juli 28). git-scm. Retrieved from git-scm: https://git-scm.com

GitHub. (2024, Juli 2024). GitHub. Retrieved from GitHub: https://github.com

GitLab. (2024, Juli 29). GitLab. Retrieved from GitLab: https://about.gitlab.com

Google. (2024, Juli 28). Angular. Retrieved from Angular: https://angular.dev

JetBrains. (2024, Juli 28). JetBrains. Retrieved from JetBrains: https://www.jetbrains.com/idea/

Markdown. (2024, Juli 28). Markdown Guide. Retrieved from Markdown Guide: https://www.markdownguide.org

Meta. (2024, August 10). React. Retrieved from React: https://react.dev

Meta Open Source. (2024, Juli 28). React. Retrieved from React: https://react.dev

Microsoft. (2024, Juli 28). TypeScript. Retrieved from TypeScript: https://www.typescriptlang.org

Microsoft. (2024, Juli 28). VisualStudioCode. Retrieved from VisualStudioCode: https://code.visualstudio.com

OpenAI. (2024, July 10). OpenAI. Retrieved from OpenAI: https://chat.openai.com/

OpenAPI. (2024, Juli 28). OpenAPI. Retrieved from OpenAPI: https://www.openapis.org

OpenJS Foundation. (2024, Juli 28). ESLint. Retrieved from ESLint: https://eslint.org

Postman, Inc. (2024, 08 13). Postman. Retrieved from Postman: https://www.postman.com

Prettier. (2024, Juli 28). Prettier. Retrieved from Prettier: https://prettier.io

SmartBear. (2024, 08 13). SwaggerEditor. Retrieved from SwaggerEditor: https://editor.swagger.io

Swagger. (2024, Juli 28). Swagger. Retrieved from Swagger: https://swagger.io/tools/swagger-ui/

The Linux Foundation. (2024, 08 13). OpenAPI. Retrieved from OpenAPI: https://www.openapis.org/what-is-openapi

You, E. (2024, Juli 28). Vue.js. Retrieved from Vue.js: https://vuejs.org