So erstellen und implementieren Sie eine Angular-Material-Anwendung

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Eine exemplarische Vorgehensweise zum Erstellen einer Angular 8-Webanwendung und einer QR-Code-Generator-App, die vollständig auf Angular basiert, während sie auf Netlify gehostet wird.

Angular ist eine der beliebtesten Optionen beim Erstellen neuer Webanwendungen. Darüber hinaus sind „Material Design“-Spezifikationen zu einer bevorzugten Wahl geworden, um heute ein minimales und ansprechendes Erlebnis zu schaffen. Daher verwendet jedes neue „Angular“-Projekt meistens die „Angular Material Design Library“, um die Komponenten zu verwenden, die den Materialdesign-Spezifikationen folgen. Von reibungslosen Animationen bis hin zu richtigem Interaktions-Feedback ist all dies bereits als Teil der offiziellen Materialdesign-Bibliothek für Angular verfügbar.

Nachdem die Webanwendung entwickelt wurde, besteht der nächste Schritt darin, sie bereitzustellen. Hier kommt „Netlify“ ins Spiel. Mit seiner sehr einfach zu bedienenden Oberfläche, der automatischen Bereitstellung, der Aufteilung des Datenverkehrs für A/B-Tests und verschiedenen anderen Funktionen ist Netlify sicherlich ein großartiges Tool.

Der Artikel wird eine exemplarische Vorgehensweise zum Erstellen einer Angular 8-Webanwendung mit der offiziellen Angular Material Design-Bibliothek sein. Wir werden eine QR-Code-Generator-Webanwendung erstellen, die vollständig auf Angular basiert und auf Netlify gehostet wird.

Dateien für dieses Tutorial finden Sie auf GitHub und eine Demoversion wird hier bereitgestellt.

Einstieg

  1. Winkel 8 installieren,
  2. Erstellen Sie ein GitHub-Konto,
  3. Installieren Sie Git auf Ihrem Computer,
  4. Erstellen Sie ein Netlify-Konto.

Hinweis : Ich werde VSCode und Microsoft Windows als bevorzugte IDE und Betriebssystem verwenden, obwohl die Schritte für jede andere IDE auf jedem anderen Betriebssystem ähnlich wären.

Nachdem die oben genannten Voraussetzungen erfüllt sind, können wir beginnen!

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Mocks & Planung

Bevor wir mit der Erstellung des Projekts beginnen, wäre es von Vorteil, im Voraus zu planen: Welche Art von Benutzeroberfläche möchten wir in unserer Anwendung? Wird es wiederverwendbare Teile geben? Wie interagiert die Anwendung mit externen Diensten?

Überprüfen Sie zuerst die UI-Mocks.

Startseite (große Vorschau)
Erstellen einer QR-Seite (große Vorschau)
Verlaufsseite (große Vorschau)

Dies sind die drei verschiedenen Seiten, die in der Anwendung enthalten sein werden. Die Homepage wird der Ausgangspunkt unserer Bewerbung sein. Das Erstellen einer QR-Seite sollte sich mit der Erstellung eines neuen QR-Codes befassen. Auf der Verlaufsseite werden alle gespeicherten QR-Codes angezeigt.

Die Mockups vermitteln nicht nur eine Vorstellung vom Aussehen und Verhalten der Anwendung, sondern trennen auch die Verantwortlichkeiten der einzelnen Seiten.

Eine Beobachtung (von den Mocks) ist, dass es scheint, dass die obere Navigationsleiste auf allen Seiten gleich ist. Somit kann die Navigationsleiste als wiederverwendbare Komponente erstellt und wiederverwendet werden.

Nachdem wir nun eine ungefähre Vorstellung davon haben, wie die Anwendung aussehen wird und was wiederverwendet werden kann, können wir beginnen.

Erstellen eines neuen Angular-Projekts

Starten Sie VSCode und öffnen Sie dann ein Terminalfenster in VSCode, um ein neues Angular-Projekt zu generieren.

Terminal in VSCode (Große Vorschau)

Das Terminal wird mit einem Standardpfad geöffnet, wie in der Eingabeaufforderung gezeigt. Sie können zu einem bevorzugten Verzeichnis wechseln, bevor Sie fortfahren; im Fall von Windows verwende ich den cd Befehl.

Navigieren zum bevorzugten Pfad (Große Vorschau)

In Zukunft verfügt angle-cli über einen Befehl zum Generieren neuer Projekte mit ng new <project-name> . Verwenden Sie einfach einen ausgefallenen Projektnamen, den Sie mögen, und drücken Sie die Eingabetaste, z. B. ng new qr .

Dies wird die Winkel-Kli-Magie auslösen; Es bietet einige Optionen zum Konfigurieren einiger Aspekte des Projekts, z. B. Hinzufügen von Winkelführungen. Basierend auf den ausgewählten Optionen wird dann das gesamte Projektgerüst generiert, das ohne Änderungen ausgeführt werden kann.

Geben Sie für dieses Tutorial Ja für das Routing ein und wählen Sie CSS für das Styling aus. Dadurch wird ein neues Angular-Projekt generiert:

Erstellen eines neuen Angular-Projekts (große Vorschau)

Wir haben jetzt ein voll funktionsfähiges Angular-Projekt. Um sicherzustellen, dass alles richtig funktioniert, können wir das Projekt ausführen, indem wir diesen Befehl im Terminal eingeben: ng serve . Uh oh, aber warten Sie, dies führt zu einem Fehler. Was könnte passiert sein?

ng server error (Große Vorschau)

Mach dir keine Sorge. Immer wenn Sie ein neues Projekt mit angle-cli erstellen, wird das gesamte Skelett in einem Ordner generiert, der nach dem Projektnamen benannt ist, der im Befehl ng new qr angegeben wurde. Hier müssen wir das aktuelle Arbeitsverzeichnis in das gerade erstellte ändern. Verwenden Sie in Windows den Befehl cd qr , um das Verzeichnis zu wechseln.

Versuchen Sie nun, das Projekt mit Hilfe von ng serve erneut auszuführen:

Projekt läuft (Große Vorschau)

Öffnen Sie einen Webbrowser, rufen Sie die URL https://localhost:4200 auf, um zu sehen, wie das Projekt ausgeführt wird. Der Befehl ng serve führt die Anwendung standardmäßig auf Port 4200 aus.

TIPP : Um es auf einem anderen Port auszuführen, verwenden wir den Befehl ng serve --port <any-port> zum Beispiel ng serve --port 3000 .

Dadurch wird sichergestellt, dass unser grundlegendes Angular-Projekt läuft. Lass uns weitermachen.

Wir müssen den Projektordner zu VSCode hinzufügen. Gehen Sie zum Menü „Datei“ und wählen Sie „Ordner öffnen“ und wählen Sie den Projektordner aus. Der Projektordner wird nun links in der Explorer-Ansicht angezeigt.

Winkelmaterialbibliothek hinzugefügt

Um die Angular-Materialbibliothek zu installieren, verwenden Sie den folgenden Befehl im Terminalfenster: ng add @angular/material . Dadurch werden (wieder) einige Fragen gestellt, z. B. welches Thema Sie möchten, ob Sie Standardanimationen wünschen, ob unter anderem Touch-Unterstützung erforderlich ist. Wir wählen einfach das standardmäßige Indigo/Pink -Design aus, Yes , um HammerJS Bibliothek und Browser-Animationen hinzuzufügen.

Winkelmaterial hinzufügen (große Vorschau)

Der obige Befehl konfiguriert auch das gesamte Projekt, um die Unterstützung für die Materialkomponenten zu ermöglichen.

  1. Es fügt Projektabhängigkeiten zu package.json hinzu,
  2. Es fügt der index.html -Datei die Roboto-Schriftart hinzu,
  3. Es fügt Ihrer index.html die Symbolschrift Material Design hinzu.
  4. Es fügt auch einige globale CSS-Stile hinzu:
    • Ränder aus dem Körper entfernen,
    • height: 100% in HTML und Text,
    • Stellen Sie Roboto als Standardanwendungsschriftart ein.

Nur um sicherzugehen, dass alles in Ordnung ist, können Sie das Projekt an dieser Stelle erneut ausführen, obwohl Sie nichts Neues bemerken werden.

Homepage hinzufügen

Unser Projektskelett ist nun fertig. Beginnen wir mit dem Hinzufügen der Homepage.

(Große Vorschau)

Wir möchten unsere Homepage einfach halten, genau wie das obige Bild. Diese Homepage verwendet einige kantige Materialkomponenten. Lassen Sie uns sezieren.

  1. Die obere Leiste ist ein einfaches HTML- nav , das eine Materialstil-Schaltfläche, mat-button , mit einem Bild und einem Text als Kind enthält. Die Balkenfarbe ist dieselbe wie die Primärfarbe, die beim Hinzufügen der Angular-Materialbibliothek ausgewählt wurde;
  2. Ein zentriertes Bild;
  3. Ein weiterer, mat-button , mit nur einem Text als Kind. Mit dieser Schaltfläche können Benutzer zur Verlaufsseite navigieren;
  4. Ein Zählabzeichen, matBadge , das an die obige Schaltfläche angehängt ist und die Anzahl der vom Benutzer gespeicherten QR-Codes anzeigt;
  5. Eine schwebende Aktionsschaltfläche, mat-fab , in der unteren rechten Ecke mit der Akzentfarbe des ausgewählten Themas.

Lassen Sie uns ein wenig abschweifen und zuerst andere erforderliche Komponenten und Dienste hinzufügen.

Kopfzeile hinzufügen

Wie zuvor geplant, sollte die Navigationsleiste wiederverwendet werden, erstellen wir sie als separate Winkelkomponente. Öffnen Sie das Terminal in VSCode und geben Sie ng gc header (kurz für ng generate component header) ein und drücken Sie die Eingabetaste. Dadurch wird ein neuer Ordner namens „header“ erstellt, der vier Dateien enthält:

  • header.component.css : wird verwendet, um Stile für diese Komponente bereitzustellen;
  • header.component.html : zum Hinzufügen von HTML-Elementen;
  • header.component.spec.ts : zum Schreiben von Testfällen;
  • header.component.ts : um die Typescript-basierte Logik hinzuzufügen.
Header-Komponente (große Vorschau)

Damit der Header so aussieht wie in den Mocks, fügen Sie den folgenden HTML-Code in header.component.html hinzu :

 <nav class="navbar" [class.mat-elevation-z8]=true> <div> <button *ngIf="showBackButton" aria-hidden=false mat-icon-button routerLink="/"> <mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon> </button> <span>{{currentTitle}}</span> </div> <button *ngIf="!showBackButton" aria-hidden=false mat-button class="button"> <img src="../../assets/qr-icon-white.png"> <span>QR Generator</span> </button> <button *ngIf="showHistoryNav" aria-hidden=false mat-button class="button" routerLink="/history"> <span>History</span> </button> </nav>

TIPP : Um die Höhe für eine beliebige Materialkomponente hinzuzufügen, verwenden [class.mat-elevation-z8]=true , der Höhenwert kann durch Ändern des z - Werts geändert werden, in diesem Fall ist es z8 . Um beispielsweise die Höhe auf 16 zu ändern, verwenden [class.mat-elevation-z16]=true .

Im obigen HTML-Snippet werden zwei Angular-Materialelemente verwendet: mat-icon und mat-button/mat-icon-button . Ihre Verwendung ist sehr einfach; Zuerst müssen wir diese beiden als Module in unserer app.module.ts hinzufügen , wie unten gezeigt:

Modulimport für mat-icon und mat-button (Große Vorschau)

Dadurch können wir diese beiden eckigen Materialelemente überall in jedem Bauteil verwenden.

Zum Hinzufügen von Materialschaltflächen wird das folgende HTML-Snippet verwendet:

 <button mat-button> Material Button </button>

In der Angular-Materialbibliothek sind verschiedene Arten von Materialschaltflächenelementen verfügbar, z. B. mat-raised-button , mat-flat-button , mat-fab und andere; Ersetzen Sie einfach den mat-button im obigen Code-Snippet durch einen anderen Typ.

Arten von Materialschaltflächen (Große Vorschau)

Das andere Element ist mat-icon , das verwendet wird, um Symbole anzuzeigen, die in der Materialsymbolbibliothek verfügbar sind. Als die Angular-Materialbibliothek am Anfang hinzugefügt wurde, wurde auch ein Verweis auf die Materialsymbolbibliothek hinzugefügt, wodurch wir Symbole aus der großen Auswahl an Symbolen verwenden konnten.

Die Verwendung ist so einfach wie:

 <mat-icon> <i class="material-icons md-32">arrow_back</i> </mat-icon>

Das verschachtelte <i> -Tag kann verwendet werden, um die Symbolgröße zu ändern (hier ist es md-32 ), wodurch die Symbolgröße 32 Pixel in Höhe und Breite beträgt. Dieser Wert kann md-24 , md-48 usw. sein. Der Wert des verschachtelten <i> -Tags ist der Name des Symbols. (Der Name kann hier für jedes andere Symbol gefunden werden.)

Barrierefreiheit

Wenn Symbole oder Bilder verwendet werden, ist es zwingend erforderlich, dass sie ausreichende Informationen für Barrierefreiheitszwecke oder für einen Screenreader-Benutzer bereitstellen. ARIA (Accessible Rich Internet Applications) definiert eine Möglichkeit, Webinhalte und Webanwendungen für Menschen mit Behinderungen zugänglicher zu machen.

Ein zu beachtender Punkt ist, dass die HTML-Elemente, die ihre native Semantik haben (z. B. nav ), keine ARIA-Attribute benötigen; Der Screenreader würde bereits wissen, dass nav ein Navigationselement ist und es als solches lesen.

Die ARIA-Spezifikationen sind in drei Kategorien unterteilt: Rollen, Zustände und Eigenschaften. Nehmen wir an, dass ein div verwendet wird, um einen Fortschrittsbalken im HTML-Code zu erstellen. Es hat keine native Semantik; Die ARIA-Rolle kann dieses Widget als Fortschrittsbalken beschreiben, die ARIA-Eigenschaft kann seine Eigenschaft bezeichnen, z. B. dass es gezogen werden kann. Der ARIA-Status beschreibt seinen aktuellen Status, wie z. B. den aktuellen Wert des Fortschrittsbalkens. Siehe den folgenden Ausschnitt:

 <div role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> </div>

In ähnlicher Weise wird ein sehr häufig verwendetes Arie-Attribut verwendet: aria-hidden=true/false . Der Wert true macht dieses Element für Screenreader unsichtbar.

Da die meisten der in dieser Anwendung verwendeten UI-Elemente eine native semantische Bedeutung haben, dienen die einzigen verwendeten ARIA-Attribute dazu, ARIA-Sichtbarkeitszustände anzugeben. Ausführliche Informationen finden Sie hier.

Die header.component.html enthält eine Logik zum Ausblenden und Anzeigen der Zurück-Schaltfläche, abhängig von der aktuellen Seite. Darüber hinaus enthält die Home-Schaltfläche auch ein Bild/Logo, das dem /assets -Ordner hinzugefügt werden sollte. Laden Sie das Bild von hier herunter und speichern Sie es im Ordner /assets .

Fügen Sie für die Gestaltung der Navigationsleiste das folgende CSS in header.component.css hinzu :

 .navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 2; background: #3f51b5; display: flex; flex-wrap: wrap; align-items: center; padding: 12px 16px; } .button { color: white; margin: 0px 10px; }

Da wir die Header-Komponente für andere Komponenten wiederverwendbar halten wollen, um zu entscheiden, was angezeigt werden soll, benötigen wir diese als Parameter von anderen Komponenten. Dies erfordert die Verwendung von @Input() Decorator, der an die Variablen bindet, die wir in header.component.html verwendet haben.

Fügen Sie diese Zeilen in der Datei header.component.ts hinzu :

 // Add these three lines above the constructor entry. @Input() showBackButton: boolean; @Input() currentTitle: string; @Input() showHistoryNav: boolean; constructor() { }

Die obigen drei Bindungen werden als Parameter von anderen Komponenten übergeben, die die Header-Komponente verwenden wird. Seine Verwendung wird klarer, wenn wir weitermachen.

Als nächstes müssen wir eine Homepage erstellen, die durch eine Angular-Komponente dargestellt werden kann. Beginnen wir also damit, eine weitere Komponente zu erstellen; ng gc home in das Terminal ein, um die Home-Komponente automatisch zu generieren. Wie zuvor wird ein neuer Ordner mit dem Namen „home“ erstellt, der vier verschiedene Dateien enthält. Bevor wir mit der Änderung dieser Dateien fortfahren, fügen wir einige Routing-Informationen zum Winkel-Routing-Modul hinzu.

Routing hinzufügen

Angular bietet eine Möglichkeit, eine URL einer bestimmten Komponente zuzuordnen. Bei jeder Navigation überwacht das Angular-Framework die URL und basierend auf den Informationen in der Datei app-routing.module.ts ; es initialisiert die gemappte Komponente. Auf diese Weise müssen verschiedene Komponenten nicht die Verantwortung für die Initialisierung anderer Komponenten übernehmen. In unserem Fall hat die Anwendung drei Seiten, die durch Klicken auf verschiedene Schaltflächen navigierbar sind. Wir erreichen dies, indem wir die Routing-Unterstützung des Angular-Frameworks nutzen.

Die Home-Komponente sollte der Ausgangspunkt der Anwendung sein. Fügen wir diese Informationen der Datei app-routing.module.ts hinzu .

Routing Home-Komponente (große Vorschau)

Die path wird als leerer String gesetzt; Dadurch können wir die Anwendungs-URL der Startseitenkomponente zuordnen, etwa google.com , die die Google-Startseite anzeigt.

TIPP : Der Pfadwert beginnt nie mit einem/ “, sondern verwendet stattdessen eine leere Zeichenfolge, obwohl Pfad wie search/coffee sein kann.

Gehen Sie zurück zur Homepage-Komponente und ersetzen Sie den Inhalt von home.component.html durch diesen:

 <app-header [showBackButton]="false" [currentTitle]=""></app-header> <app-profile></app-profile> <!-- FAB Fixed --> <button mat-fab class="fab-bottom-right" routerLink="/create"> <mat-icon> <i class="material-icons md-48">add</i> </mat-icon> </button>

Die Heimkomponente besteht aus drei Teilen:

  1. Die wiederverwendbare Header-Komponente <app-header> ,
  2. <app-profile> ,
  3. Die schwebende Aktionsschaltfläche unten rechts.

Das obige HTML-Snippet zeigt, wie die wiederverwendbare Header-Komponente in anderen Komponenten verwendet wird; Wir verwenden einfach den Komponentenselektor und übergeben die erforderlichen Parameter.

Die Profilkomponente wird erstellt, um als Hauptteil für die Homepage verwendet zu werden – wir werden sie bald erstellen.

Die schwebende Aktionsschaltfläche mit dem + -Symbol ist eine Art Winkelmaterial-Schaltfläche vom Typ mat-fab unten rechts auf dem Bildschirm. Es verfügt über die Attributdirektive routerLink , die die in app-routing.module.ts bereitgestellten Routeninformationen für die Navigation verwendet. In diesem Fall hat die Schaltfläche den Routenwert als /create , der der create-Komponente zugeordnet wird.

Um die Erstellungsschaltfläche unten rechts schweben zu lassen, fügen Sie den folgenden CSS-Code in home.component.css hinzu :

 .fab-bottom-right { position: fixed; left: auto; bottom: 5%; right: 10%; }

Da die Profilkomponente den Inhalt der Homepage verwalten soll, lassen wir home.component.ts intakt.

Profilkomponente hinzufügen

Öffnen Sie das Terminal, ng gc profile ein und drücken Sie die Eingabetaste, um die Profilkomponente zu generieren. Wie bereits geplant, wird diese Komponente den Hauptteil der Homepage verwalten. Öffnen profile.component.html und ersetzen Sie den Inhalt durch diesen:

 <div class="center profile-child"> <img class="avatar" src="../../assets/avatar.png"> <div class="profile-actions"> <button mat-raised-button matBadge="{{historyCount}}" matBadgeOverlap="true" matBadgeSize="medium" matBadgeColor="accent" color="primary" routerLink="/history"> <span>History</span> </button> </div> </div>

Das obige HTML-Snippet zeigt, wie das matBadge Element der Materialbibliothek verwendet wird. Um es hier verwenden zu können, müssen wir der üblichen Vorgehensweise zum Hinzufügen von MatBadgeModule zur Datei app.module.ts app.module.ts . Abzeichen sind kleine bildliche Statusbeschreibungen für UI-Elemente wie Schaltflächen oder Symbole oder Texte. In diesem Fall wird es mit einer Schaltfläche verwendet, um die Anzahl der vom Benutzer gespeicherten QR anzuzeigen. Das Badge der Winkelmaterialbibliothek verfügt über verschiedene andere Eigenschaften, z. B. das Festlegen der Position des Badges mit matBadgePosition , matBadgeSize zum Angeben der Größe und matBadgeColor zum Festlegen der Badge-Farbe.

Ein weiteres Bild-Asset muss dem Assets-Ordner hinzugefügt werden: Download. Speichern Sie dasselbe im /assets -Ordner des Projekts.

Öffnen Sie profile.component.css und fügen Sie Folgendes hinzu:

 .center { top: 50%; left: 50%; position: absolute; transform: translate(-50%, -50%); } .profile-child { display: flex; flex-direction: column; align-items: center; } .profile-actions { padding-top: 20px; } .avatar { border-radius: 50%; width: 180px; height: 180px; }

Das obige CSS wird die Benutzeroberfläche wie geplant erreichen.

Im weiteren Verlauf benötigen wir eine Art Logik, um den Verlaufszählerwert zu aktualisieren, da er sich in dem zuvor verwendeten matBadge widerspiegelt. Öffnen Sie profile.component.ts und fügen Sie das folgende Snippet entsprechend hinzu:

 export class ProfileComponent implements OnInit { historyCount = 0; constructor(private storageUtilService: StorageutilService) { } ngOnInit() { this.updateHistoryCount(); } updateHistoryCount() { this.historyCount = this.storageUtilService.getHistoryCount(); } }

Wir haben StorageutilService hinzugefügt, aber wir haben bis jetzt keinen solchen Dienst erstellt. Wir ignorieren den Fehler und haben unsere Profilkomponente fertiggestellt, die auch unsere Homepage-Komponente abschließt. Wir werden diese Profilkomponente erneut besuchen, nachdem wir unseren Speicherdienstprogrammdienst erstellt haben. Okay, dann machen wir das.

Lokaler Speicher

HTML5 bietet eine Webspeicherfunktion, mit der Daten lokal gespeichert werden können. Dies bietet im Vergleich zu Cookies viel mehr Speicherplatz – mindestens 5 MB gegenüber 4 KB. Es gibt zwei Arten von Webspeicher mit unterschiedlichem Umfang und unterschiedlicher Lebensdauer: Local und Session . Ersteres kann Daten dauerhaft speichern, während letzteres temporär und für eine einzelne Sitzung ist. Die Entscheidung zur Auswahl des Typs kann auf dem Anwendungsfall basieren, in unserem Szenario möchten wir sitzungsübergreifend speichern, also gehen wir zum lokalen Speicher.

Jedes Datenelement wird in einem Schlüssel/Wert-Paar gespeichert. Wir verwenden den Text, für den der QR generiert wird, als Schlüssel und das als Base64-String codierte QR-Bild als Wert. Erstellen Sie einen Entitätsordner, erstellen Sie in dem Ordner eine neue qr-object.ts- Datei und fügen Sie das Code-Snippet wie gezeigt hinzu:

QR-Entitätsmodell (große Vorschau)

Der Inhalt der Klasse:

 export class QR { text: string; imageBase64: string; constructor(text: string, imageBase64: string) { this.imageBase64 = imageBase64; this.text = text; } }

Immer wenn der Benutzer den generierten QR speichert, erstellen wir ein Objekt der oben genannten Klasse und speichern dieses Objekt mithilfe des Speicherdienstprogramms.

Erstellen Sie einen neuen Dienstordner, wir werden viele Dienste erstellen, es ist besser, sie zu gruppieren.

Dienstordner (große Vorschau)

Ändern Sie das aktuelle Arbeitsverzeichnis in services, cd services , um einen neuen Dienst mit ng gs <any name> zu erstellen. Dies ist eine Abkürzung für ng generate service <any name> , ng gs storageutil und drücken Sie die Eingabetaste

Dadurch werden zwei Dateien erstellt:

  • storageutil.service.ts
  • storageutil.service.spec.ts

Letzteres dient zum Schreiben von Unit-Tests. Öffnen Sie storageutil.service.ts und fügen Sie Folgendes hinzu:

 private historyCount: number; constructor() { } saveHistory(key : string, item :string) { localStorage.setItem(key, item) this.historyCount = this.historyCount + 1; } readHistory(key : string) : string { return localStorage.getItem(key) } readAllHistory() : Array<QR> { const qrList = new Array<QR>(); for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); const value = localStorage.getItem(key); if (key && value) { const qr = new QR(key, value); qrList.push(qr); } } this.historyCount = qrList.length; return qrList; } getHistoryCount(): number { if (this.historyCount) { return this.historyCount; } this.readAllHistory(); return this.historyCount; } deleteHistory(key : string) { localStorage.removeItem(key) this.historyCount = this.historyCount - 1; }

Importieren Sie die qr-object-Klasse, um Fehler zu korrigieren. Um die lokale Speicherfunktion zu verwenden, müssen Sie nichts Neues importieren. Verwenden Sie einfach das Schlüsselwort localStorage , um Werte basierend auf einem Schlüssel zu speichern oder abzurufen.

Öffnen Sie nun die Datei profile.component.ts erneut und importieren Sie die Klasse StorageutilService , um die Profilkomponente ordnungsgemäß abzuschließen.

Wenn wir das Projekt ausführen, können wir sehen, dass die Homepage wie geplant verfügbar ist.

QR-Seite erstellen hinzugefügt

Wir haben unsere Homepage fertig, obwohl die Schaltfläche "Erstellen/Hinzufügen" nichts bewirkt. Keine Sorge, die eigentliche Logik wurde bereits geschrieben. Wir haben eine routerLink Direktive verwendet, um den Basispfad der URL in /create zu ändern, aber der Datei app-routing.module.ts wurde keine Zuordnung hinzugefügt.

Lassen Sie uns eine Komponente erstellen, die sich mit der Erstellung neuer QR-Codes befasst, ng gc create-qr ein und drücken Sie die Eingabetaste, um eine neue Komponente zu generieren.

Öffnen Sie die Datei app-routing.module.ts und fügen Sie den folgenden Eintrag zum routes -Array hinzu:

 { path: 'create', component: CreateQrComponent },

Dadurch wird die CreateQRComponent der URL /create zugeordnet.

Öffnen Sie create-qr.components.html und ersetzen Sie den Inhalt durch diesen:

 <app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <mat-card class="qrCard" [class.mat-elevation-z12]=true> <div class="qrContent"> <!--Close button section--> <div class="closeBtn"> <button mat-icon-button color="accent" routerLink="/" matTooltip="Close"> <mat-icon> <i class="material-icons md-48">close</i> </mat-icon> </button> </div> <!--QR code image section--> <div class="qrImgDiv"> <img *ngIf="!showProgressSpinner" src={{qrCodeImage}} width="200px" height="200px"> <mat-spinner *ngIf="showProgressSpinner"></mat-spinner> <div class="actionButtons" *ngIf="!showProgressSpinner"> <button mat-icon-button color="accent" matTooltip="Share this QR"> <mat-icon> <i class="material-icons md-48">share</i> </mat-icon> </button> <button mat-icon-button color="accent" (click)="saveQR()" matTooltip="Save this QR"> <mat-icon> <i class="material-icons md-48">save</i> </mat-icon> </button> </div> </div> <!--Textarea to write any text or link--> <div class="qrTextAreaDiv"> <mat-form-field> <textarea matInput [(ngModel)]="qrText" cdkTextareaAutosize cdkAutosizeMinRows="4" cdkAutosizeMaxRows="4" placeholder="Enter a website link or any text..."></textarea> </mat-form-field> </div> <!--Create Button--> <div class="createBtnDiv"> <button class="createBtn" mat-raised-button color="accent" matTooltip="Create new QR code" matTooltipPosition="above" (click)="createQrCode()">Create</button> </div> </div> </mat-card>

Das obige Snippet verwendet viele Elemente der Angular-Materialbibliothek. Sie hat wie geplant eine Kopfkomponentenreferenz, in der die erforderlichen Parameter übergeben werden. Als nächstes kommt der Hauptteil der Erstellungsseite; Es besteht aus einer eckigen Materialkarte oder mat-card die zentriert und bis zu 12 Pixel erhöht ist, da [class.mat-elevation-z12]=true verwendet wird.

Die Materialkarte ist nur eine andere Art von Container, der wie jedes andere div -Tag verwendet werden kann. Obwohl die Materialbibliothek einige Eigenschaften bereitstellt, um gut definierte Informationen in einer mat-card wie z. B. Bildplatzierung, Titel, Untertitel, Beschreibung und Aktion, wie unten zu sehen ist.

Kartenbeispiel (große Vorschau)

Im obigen HTML-Snippet haben wir mat-card wie jeden anderen Container verwendet. Ein weiteres verwendetes Materialbibliothekselement ist matTooltip ; Es ist nur ein weiterer benutzerfreundlicher Tooltip, der angezeigt wird, wenn der Benutzer mit der Maus über ein Element fährt oder lange darauf drückt. Verwenden Sie einfach das folgende Snippet, um den Tooltip anzuzeigen:

 matTooltip="Any text you want to show"

Es kann mit Symbolschaltflächen oder anderen UI-Elementen verwendet werden, um zusätzliche Informationen zu vermitteln. Im Anwendungskontext werden Informationen zur Symbolschaltfläche „Schließen“ angezeigt. Um die Platzierung des Tooltips zu ändern, wird matTooltipPosition verwendet:

 matTooltip="Any text you want to show" matTooltipPosition="above"

Neben matTooltip wird mat-spinner spinner verwendet, um den Ladefortschritt anzuzeigen. Wenn der Benutzer auf die Schaltfläche „Erstellen“ klickt, wird ein Netzwerkaufruf getätigt. Dies ist, wenn das Fortschritts-Drehrad angezeigt wird. Wenn der Netzwerkaufruf mit Ergebnis zurückkehrt, blenden wir einfach den Spinner aus. Es kann einfach so verwendet werden:

 <mat-spinner *ngIf="showProgressSpinner"></mat-spinner>

showProgressSpinner ist eine boolesche Variable, die zum Ein-/Ausblenden des Fortschritts-Spinners verwendet wird. Die Bibliothek bietet auch einige andere Parameter wie [color]='accent' zum Ändern der Farbe, [mode]='indeterminate' zum Ändern des Fortschritts-Spinnertyps. Ein unbestimmter Fortschritts-Spinner zeigt den Fortschritt der Aufgabe nicht an, während ein bestimmter Fortschritt unterschiedliche Werte haben kann, um den Aufgabenfortschritt widerzuspiegeln. Hier wird ein unbestimmter Spinner verwendet, da wir nicht wissen, wie lange der Netzwerkaufruf dauern wird.

Die Materialbibliothek stellt eine Variante von textarea bereit, die der Materialrichtlinie entspricht, aber sie kann nur als Nachkomme von mat-form-field verwendet werden. Die Verwendung des Material-Textbereichs ist genauso einfach wie der Standard-HTML-Bereich, wie unten gezeigt:

 <mat-form-field> <textarea matInput placeholder="Hint text"></textarea> </mat-form-field>

matInput ist eine Direktive, die es dem nativen input -Tag ermöglicht, mit mat-form-field zu arbeiten. Die placeholder ermöglicht das Hinzufügen eines beliebigen Hinweistextes für den Benutzer.

TIPP : Verwenden Sie die cdkTextareaAutosize -Eigenschaft cdkTextareaAutosize, um die Größe automatisch zu ändern. Verwenden Sie cdkAutosizeMinRows und cdkAutosizeMaxRows , um Zeilen und Spalten festzulegen, und alle drei zusammen, damit die Größe des Textbereichs automatisch angepasst wird, bis er das festgelegte maximale Zeilen- und Spaltenlimit erreicht.

Um alle diese Materialbibliothekselemente zu verwenden, müssen wir sie in der Datei app.module.ts hinzufügen.

Erstellen von QR-Modul-Importen (Große Vorschau)

Im HTML wird ein Platzhalterbild verwendet. Laden Sie es herunter und speichern Sie es im Ordner /assets .

Das obige HTML erfordert auch CSS-Styling, öffnen Sie also die Datei create-qr.component.ts und fügen Sie Folgendes hinzu:

 .qrCard { display: flex; flex-direction: column; align-items: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20%; height: 65%; padding: 50px 20px; } .qrContent { display: flex; flex-direction: column; align-items: center; width: 100%; } .qrTextAreaDiv { width: 100%; display: flex; flex-direction: row; justify-content: center; padding: 0px 0px; position: absolute; bottom: 10%; } .createBtn { left: 50%; transform: translate(-50%, 0px); width: 80%; } .createBtnDiv { position: absolute; bottom: 5%; width: 100%; } .closeBtn { display: flex; flex-direction: row-reverse; align-items: flex-end; width: 100%; margin-bottom: 20px; } .closeBtnFont { font-size: 32px; color: rgba(0,0,0,0.75); } .qrImgDiv { top: 20%; position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; } .actionButtons { display: flex; flex-direction: row; padding-top: 20px; }

Lassen Sie uns die Benutzeroberfläche mit Logik verbinden. Öffnen Sie die Datei create-qr.component.ts und fügen Sie den folgenden Code hinzu, wobei Sie die bereits vorhandenen Zeilen beibehalten:

 export class CreateQrComponent implements OnInit { qrCodeImage = '../../../assets/download.png'; showProgressSpinner = false; qrText: string; currentQR; showBackButton = true; title = 'Generate New QR Code'; showHistoryNav = true; constructor(private snackBar: MatSnackBar, private restutil: RestutilService, private storageService: StorageutilService) { } ngOnInit() { } createQrCode() { //Check if any value is given for the qr code text if (!!this.qrText) { //Make the http call to load qr code this.loadQRCodeImage(this.qrText); } else { //Show snackbar this.showSnackbar('Enter some text first') } } public loadQRCodeImage(text: string) { // Show progress spinner as the request is being made this.showProgressSpinner = true; // Trigger the API call this.restutil.getQRCode(text).subscribe(image =>{ // Received the result - as an image blob - require parsing this.createImageBlob(image); }, error => { console.log('Cannot fetch QR code from the url', error) // Hide the spinner - show a proper error message this.showProgressSpinner = false; }); } private createImageBlob(image: Blob) { // Create a file reader to read the image blob const reader = new FileReader(); // Add event listener for "load" - invoked once the blob reading is complete reader.addEventListener('load', () => { this.qrCodeImage = reader.result.toString(); //Hide the progress spinner this.showProgressSpinner = false; this.currentQR = reader.result.toString(); }, false); // Read image blob if it is not null or undefined if (image) { reader.readAsDataURL(image); } } saveQR() { if (!!this.qrText) { this.storageService.saveHistory(this.qrText, this.currentQR); this.showSnackbar('QR saved') } else { //Show snackbar this.showSnackbar('Enter some text first') } } showSnackbar(msg: string) { //Show snackbar this.snackBar.open(msg, '', { duration: 2000, }); } }

Um Benutzern kontextbezogene Informationen bereitzustellen, verwenden wir auch MatSnackBar aus der Materialdesignbibliothek. Dies wird als Popup unterhalb des Bildschirms angezeigt und bleibt einige Sekunden lang bestehen, bevor es verschwindet. Dies ist kein Element, sondern ein Dienst, der aus dem Typescript-Code aufgerufen werden kann.

Das obige Snippet mit dem Methodennamen showSnackbar zeigt, wie eine Snackbar geöffnet wird, aber bevor sie verwendet werden kann, müssen wir den MatSnackBar Eintrag in der Datei app.module.ts hinzufügen , genau wie wir es für andere Materialbibliothekselemente getan haben.

TIPP : In neueren Versionen der Angular-Materialbibliothek gibt es keine einfache Möglichkeit, das Styling der Snackbar zu ändern. Stattdessen muss man zwei Ergänzungen zum Code vornehmen.

Verwenden Sie zunächst das folgende CSS, um die Hintergrund- und Vordergrundfarben zu ändern:

 ::ng-deep snack-bar-container.snackbarColor { background-color: rgba(63, 81, 181, 1); } ::ng-deep .snackbarColor .mat-simple-snackbar { color: white; }

Verwenden Sie zweitens eine Eigenschaft namens panelClass , um den Stil auf die obige CSS-Klasse festzulegen:

 this.snackBar.open(msg, '', { duration: 2000, panelClass: ['snackbarColor'] });

Die beiden obigen Kombinationen ermöglichen ein benutzerdefiniertes Styling für die Snackbar-Komponente der Materialdesignbibliothek.

Damit sind die Schritte zum Erstellen einer QR-Seite abgeschlossen, aber es fehlt noch ein Teil. Beim Überprüfen der Datei create-qr.component.ts wird ein Fehler bezüglich des fehlenden Teils angezeigt. Das fehlende Teil dieses Puzzles ist RestutilService , das für das Abrufen des QR-Code-Bildes von der Drittanbieter-API verantwortlich ist.

Ändern Sie im Terminal das aktuelle Verzeichnis in services, indem Sie ng gs restutil und die Eingabetaste drücken. Dadurch werden die RestUtilService-Dateien erstellt. Öffnen Sie die Datei restutil.service.ts und fügen Sie dieses Snippet hinzu:

 private edgeSize = '300'; private BASE_URL = 'https://api.qrserver.com/v1/create-qr-code/?data={data}!&size={edge}x{edge}'; constructor(private httpClient: HttpClient) { } public getQRCode(text: string): Observable { // Create the url with the provided data and other options let url = this.BASE_URL; url = url.replace("{data}", text).replace(/{edge}/g, this.edgeSize); // Make the http api call to the url return this.httpClient.get(url, { responseType: 'blob' }); } private edgeSize = '300'; private BASE_URL = 'https://api.qrserver.com/v1/create-qr-code/?data={data}!&size={edge}x{edge}'; constructor(private httpClient: HttpClient) { } public getQRCode(text: string): Observable { // Create the url with the provided data and other options let url = this.BASE_URL; url = url.replace("{data}", text).replace(/{edge}/g, this.edgeSize); // Make the http api call to the url return this.httpClient.get(url, { responseType: 'blob' }); }

Der obige Dienst ruft das QR-Bild von der Drittanbieter-API ab, und da die Antwort kein JSON-Typ, sondern ein Bild ist, geben wir im obigen Snippet den responseType als 'blob' an.

Angular stellt die HttpClient -Klasse bereit, um mit jedem HTTP-unterstützenden Server zu kommunizieren. Es bietet viele Funktionen wie das Filtern der Anfrage, bevor sie ausgelöst wird, das Zurückholen der Antwort, das Ermöglichen der Verarbeitung der Antwort über Rückrufe und andere. Um dasselbe zu verwenden, fügen Sie einen Eintrag für das HttpClientModule in der Datei app.module.ts hinzu .

Importieren Sie schließlich diesen Dienst in die Datei create-qr.component.ts , um die Erstellung des QR-Codes abzuschließen.

Aber warte! Es gibt ein Problem mit der obigen Erstellungs-QR-Logik. Wenn der Benutzer immer wieder denselben Text verwendet, um den QR zu generieren, führt dies zu einem Netzwerkaufruf. Eine Möglichkeit, dies zu beheben, besteht darin, die Anfrage basierend zwischenzuspeichern und so die Antwort aus dem Cache zu bedienen, wenn der Anfragetext gleich ist.

Caching-Anfrage

Angular bietet eine vereinfachte Methode zum Durchführen von HTTP-Aufrufen, HttpClient, zusammen mit HttpInterceptors, um HTTP-Anforderungen oder -Antworten an und von Servern zu untersuchen und umzuwandeln. Es kann für die Authentifizierung oder das Caching und vieles mehr verwendet werden, mehrere Interceptoren können hinzugefügt und zur weiteren Verarbeitung verkettet werden. In diesem Fall fangen wir Anfragen ab und liefern die Antwort aus dem Cache, wenn der QR-Text gleich ist.

Erstellen Sie einen Interceptor-Ordner und dann eine Datei cache-interceptor.ts :

Cache Interceptor (große Vorschau)

Fügen Sie der Datei das folgende Code-Snippet hinzu:

 import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { tap } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class RequestCachingService implements HttpInterceptor { private cacheMap = new Map<string, HttpResponse<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { const cachedResponse = this.cacheMap.get(req.urlWithParams); if (cachedResponse) { return of(cachedResponse); } return next.handle(req).pipe(tap(event => { if (event instanceof HttpResponse) { this.cacheMap.set(req.urlWithParams, event); } })) } } import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpResponse, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { tap } from 'rxjs/operators'; import { of, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class RequestCachingService implements HttpInterceptor { private cacheMap = new Map<string, HttpResponse<any>>(); constructor() { } intercept(req: HttpRequest , next: HttpHandler): Observable<HttpEvent<any>> { const cachedResponse = this.cacheMap.get(req.urlWithParams); if (cachedResponse) { return of(cachedResponse); } return next.handle(req).pipe(tap(event => { if (event instanceof HttpResponse) { this.cacheMap.set(req.urlWithParams, event); } })) } }

Im obigen Code-Snippet haben wir eine Zuordnung, bei der der Schlüssel die Anforderungs-URL und die Antwort der Wert ist. Wir prüfen, ob die aktuelle URL in der Karte vorhanden ist; if it is, then return the response (the rest is handled automatically). If the URL is not in the map, we add it.

We are not done yet. An entry to the app.module.ts is required for its proper functioning. Add the below snippet:

 import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { CacheInterceptor } from './interceptor/cache-interceptor'; providers: [ { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true } ],

This adds the caching feature to our application. Let's move on to the third page, the History page.

Adding The History Page

All the saved QR codes will be visible here. To create another component, open terminal type ng gc history and press Enter.

Open history.component.css and add the below code:

 .main-content { padding: 5% 10%; } .truncate { width: 90%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .center-img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; }

Open history.component.html and replace the content with this:

 <app-header [showBackButton]="showBackButton" [currentTitle]="title" [showHistoryNav]="showHistoryNav"></app-header> <div class="main-content"> <mat-grid-list cols="4" rowHeight="500px" *ngIf="historyList.length > 0"> <mat-grid-tile *ngFor="let qr of historyList"> <mat-card> <img mat-card-image src="{{qr.imageBase64}}"> <mat-card-content> <div class="truncate"> {{qr.text}} </div> </mat-card-content> <mat-card-actions> <button mat-button (click)="share(qr.text)">SHARE</button> <button mat-button color="accent" (click)="delete(qr.text)">DELETE</button> </mat-card-actions> </mat-card> </mat-grid-tile> </mat-grid-list> <div class="center-img" *ngIf="historyList.length == 0"> <img src="../../assets/no-see.png" width="256" height="256"> <span>Nothing to see here</span> </div> </div>

As usual, we have the header component at the top. Then, the rest of the body is a grid list that will show all the saved QR codes as individual mat-card . For the grid view, we are using mat-grid-list from the Angular material library. As per the drill, before we can use it, we have to first add it to the app.module.ts file.

Mat Grid List fungiert als Container mit mehreren untergeordneten Kacheln namens mat-grid-tile . Im obigen HTML-Snippet wird jede Kachel mithilfe von mat-card erstellt, wobei einige ihrer Eigenschaften für die generische Platzierung anderer UI-Elemente verwendet werden. Wir können die number of columns und rowHeight , die zur automatischen Berechnung der Breite verwendet werden. Im obigen Snippet geben wir sowohl die Anzahl der Spalten als auch den rowHeight Wert an.

Wir verwenden ein Platzhalterbild, wenn der Verlauf leer ist, laden Sie es herunter und fügen Sie es dem Assets-Ordner hinzu.

Um die Logik zum Auffüllen all dieser Informationen zu implementieren, öffnen Sie die Datei history.component.ts und fügen Sie das folgende Snippet in die HistoryComponent -Klasse ein:

 showBackButton = true; title = 'History'; showHistoryNav = false; historyList; constructor(private storageService: StorageutilService, private snackbar: MatSnackBar ) { } ngOnInit() { this.populateHistory(); } private populateHistory() { this.historyList = this.storageService.readAllHistory(); } delete(text: string) { this.storageService.deleteHistory(text); this.populateHistory(); } share(text: string) { this.snackbar.open(text, '', {duration: 2000,}) }

Die obige Logik ruft einfach alle gespeicherten QR ab und füllt die Seite damit. Benutzer können den gespeicherten QR löschen, wodurch der Eintrag aus dem lokalen Speicher gelöscht wird.

Das beendet also unsere Geschichtskomponente ... oder nicht? Wir müssen noch die Routenzuordnung für diese Komponente hinzufügen. Öffnen Sie app-routing.module.ts und fügen Sie auch eine Zuordnung für die Verlaufsseite hinzu:

 { path: 'history', component: HistoryComponent },

Das gesamte Routen-Array sollte jetzt so aussehen:

 const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'create', component: CreateQrComponent }, { path: 'history', component: HistoryComponent }, ];

Jetzt ist ein guter Zeitpunkt, um die Anwendung auszuführen, um den vollständigen Ablauf zu überprüfen. Öffnen Sie also das Terminal, geben Sie ng serve ein und drücken Sie die Eingabetaste. Gehen Sie dann zu localhost:4200 , um die Funktionsfähigkeit der Anwendung zu überprüfen.

Zu GitHub hinzufügen

Bevor Sie mit dem Bereitstellungsschritt fortfahren, sollten Sie das Projekt einem GitHub-Repository hinzufügen.

  1. Öffnen Sie GitHub.
  2. Erstellen Sie ein neues Repository.
  3. GitHub neues Repository (große Vorschau)
  4. Verwenden Sie in VS Code das Terminal und befolgen Sie den ersten Befehlssatz, der in der Schnellstartanleitung erwähnt wird, um alle Projektdateien zu übertragen.
  5. Hinzufügen eines Projekts in GitHub (große Vorschau)

Aktualisieren Sie einfach die Seite, um zu überprüfen, ob alle Dateien sichtbar sind. Ab diesem Zeitpunkt werden alle Git-Änderungen (wie Commit, Pull/Push) in diesem neu erstellten Repository widergespiegelt.

Netlify und Bereitstellung

Unsere Anwendung wird auf unserem lokalen Computer ausgeführt, aber damit andere darauf zugreifen können, sollten wir sie auf einer Cloud-Plattform bereitstellen und unter einem Domänennamen registrieren. Hier kommt Netlify ins Spiel. Es bietet kontinuierliche Bereitstellungsdienste, Integration mit GitHub und viele weitere Funktionen, von denen Sie profitieren können. Im Moment möchten wir den globalen Zugriff auf unsere Anwendung ermöglichen. Lass uns anfangen.

  1. Melden Sie sich bei Netlify an.
  2. Klicken Sie im Dashboard auf die Schaltfläche Neue Site von Git .
  3. Netlify neue Seite (große Vorschau)
  4. Klicken Sie im nächsten Bildschirm auf GitHub.
  5. Netlify Select Git Provider (Große Vorschau)
  6. Autorisieren Sie Netlify, um auf Ihre GitHub-Repositories zugreifen zu können.
  7. Netlify GitHub-Autorisierung (große Vorschau)
  8. Suchen Sie nach dem neu erstellten qr Repository und wählen Sie es aus.
  9. Netlify GitHub-Repository-Auswahl (große Vorschau)
  10. Netlify erlaubt uns im nächsten Schritt, den GitHub-Repository-Zweig für Deployments auszuwählen. Normalerweise verwendet man den master Zweig, aber man kann auch einen separaten release -Zweig haben, der nur Release-bezogene und stabile Features enthält.
  11. Netlify erstellen und bereitstellen (große Vorschau)

Da es sich um eine Angular-Webanwendung handelt, fügen Sie ng build --prod als build-Befehl hinzu. Veröffentlichte Verzeichnisse sind dist/qr , wie in der Datei angular.json erwähnt.

Angular Build Path (Große Vorschau)

Klicken Sie nun auf die Schaltfläche Deploy site , die mit dem Befehl ng build --prod einen Projektaufbau auslöst und die Datei an dist/qr ausgibt.

Da wir Netlify die Pfadinformationen zur Verfügung gestellt haben, werden automatisch die richtigen Dateien für die Wartung der Webanwendung abgerufen. Netlify fügt unserer Anwendung standardmäßig eine zufällige Domain hinzu.

Netlify-Site bereitgestellt (große Vorschau)

Sie können jetzt auf den Link auf der obigen Seite klicken, um von überall aus auf die Anwendung zuzugreifen. Schließlich wurde die Anwendung bereitgestellt.

Benutzerdefinierten Domain

Im obigen Bild wird die URL für unsere Anwendung angezeigt, während die Subdomain zufällig generiert wird. Lass uns das ändern.

Klicken Sie auf die Schaltfläche Domain settings , dann im Abschnitt Benutzerdefinierte Domains auf das 3-Punkte-Menü und wählen Sie Edit site name aus.

Benutzerdefinierte Domäne (große Vorschau)

Dies öffnet ein Popup, in dem ein neuer Site-Name eingegeben werden kann; Dieser Name sollte innerhalb der Netlify-Domain eindeutig sein. Geben Sie einen beliebigen verfügbaren Standortnamen ein und klicken Sie auf Speichern .

Name der Website (große Vorschau)

Jetzt wird der Link zu unserer Anwendung mit dem neuen Site-Namen aktualisiert.

Split-Tests

Eine weitere coole Funktion von Netlify ist das Split-Testing. Es ermöglicht die Aufteilung des Datenverkehrs, sodass unterschiedliche Benutzergruppen mit unterschiedlichen Anwendungsbereitstellungen interagieren. Wir können neue Funktionen zu einem anderen Branch hinzufügen und den Traffic auf diese Branch-Bereitstellung aufteilen, den Traffic analysieren und dann den Feature-Branch mit dem Haupt-Deployment-Branch zusammenführen. Lass es uns konfigurieren.

Voraussetzung für die Aktivierung von Split-Testing ist ein GitHub-Repository mit mindestens zwei Branches. Wechseln Sie zum App-Repository in GitHub, das zuvor erstellt wurde, und erstellen Sie einen neuen Zweig a .

Neuen Zweig erstellen (Große Vorschau)

Das Repository hat nun einen master Branch und a Branch. Netlify muss für Branch-Bereitstellungen konfiguriert werden, öffnen Sie also das Netlify-Dashboard und klicken Sie auf Settings . Klicken Sie auf der linken Seite auf Build & Deploy , dann auf Continuous Deployment und dann auf der rechten Seite im Abschnitt Deploy contexts auf Edit settings .

Branch-Bereitstellungen (große Vorschau)

Wählen Sie im Unterabschnitt Branch deploys die Option „Lassen Sie mich einzelne Branches hinzufügen“, geben Sie die Branch-Namen ein und speichern Sie sie.

Das Bereitstellen von Verzweigungen ist eine weitere nützliche Funktion von Netlify; Wir können auswählen, welche GitHub-Repository-Zweige bereitgestellt werden sollen, und wir können auch Vorschauen für jede Pull-Anforderung an den master Zweig vor dem Zusammenführen aktivieren. Dies ist eine nette Funktion, die es Entwicklern ermöglicht, ihre Änderungen tatsächlich live zu testen, bevor sie ihre Codeänderungen zum Hauptbereitstellungszweig hinzufügen.

Klicken Sie nun oben auf der Seite auf die Registerkarte Split Testing . Die Split-Test-Konfigurationen werden hier vorgestellt.

Split-Tests (große Vorschau)

Wir können den Branch (anders als den Produktionsbranch) auswählen – in diesem Fall a . Wir können auch mit den Einstellungen für die Aufteilung des Datenverkehrs herumspielen. Basierend auf dem Traffic-Prozentsatz, der jedem Zweig zugeteilt wurde, leitet Netlify einige Benutzer zu der Anwendung um, die über den a -Zweig bereitgestellt wird, und andere zum master Zweig. Klicken Sie nach der Konfiguration auf die Schaltfläche Start test , um die Aufteilung des Datenverkehrs zu aktivieren.

TIPP : Netlify erkennt möglicherweise nicht, dass das verbundene GitHub-Repository mehr als einen Zweig hat, und gibt möglicherweise diesen Fehler aus:

Split-Test-Fehler (große Vorschau)

Um dies zu beheben, verbinden Sie sich einfach über die Build & Deploy Optionen erneut mit dem Repository.

Netlify bietet auch viele andere Funktionen. Wir sind gerade einige seiner nützlichen Funktionen durchgegangen, um zu demonstrieren, wie einfach die Konfiguration verschiedener Aspekte von Netlify ist.

Damit sind wir am Ende unserer Reise angelangt. Wir haben erfolgreich ein Angular-Material-Design basierend auf einer Webanwendung erstellt und auf Netlify bereitgestellt.

Fazit

Angular ist ein großartiges und beliebtes Framework für die Entwicklung von Webanwendungen. Mit der offiziellen Materialdesignbibliothek von Angular ist es viel einfacher, Anwendungen zu erstellen, die den Materialdesignspezifikationen für eine sehr natürliche Interaktion mit den Benutzern entsprechen. Darüber hinaus sollte die mit einem großartigen Framework entwickelte Anwendung eine großartige Plattform für die Bereitstellung nutzen, und Netlify ist genau das. Mit ständiger Weiterentwicklung, großartigem Support und einer Fülle von Funktionen ist es sicherlich eine großartige Plattform, um Webanwendungen oder statische Websites der Masse zugänglich zu machen. Hoffentlich hilft dieser Artikel beim Einstieg in ein neues Angular-Projekt von der Idee bis zur Bereitstellung.

Weiterführende Lektüre

  • Eckige Architektur
  • Mehr eckige Materialkomponenten
  • Mehr über Netlify-Funktionen