1. Hinweis
Angular-Signale bringen drei reaktive Primitive in das Angular ein, das du kennst und magst. Dadurch wird die Entwicklung vereinfacht und du kannst standardmäßig schnellere Apps entwickeln.
Inhalt
- Du lernst die drei reaktiven Primitiven kennen, die mit Angular-Signalen eingeführt werden:
signal()
,computed()
undeffect()
. - Angular-Signale für Angular-Cipher-Spiele nutzen Verschlüsselungsverfahren sind Systeme zum Verschlüsseln und Entschlüsseln von Daten. In diesem Spiel können Nutzer eine geheime Nachricht durch Ziehen und Ablegen von Hinweisen entschlüsseln, um eine Chiffre zu lösen, die Nachricht anpassen und die URL teilen, um geheime Nachrichten an Freunde zu senden.
Voraussetzungen
- Kenntnisse in Angular und Typescript
- Empfohlen: Im Video Rethinking Reactivity with Signals (in englischer Sprache) erfahren Sie mehr über die Angular-Signale-Bibliothek.
2. Code abrufen
Alles, was Sie für dieses Projekt benötigen, befindet sich in einem StackBlitz. Stackblitz ist die empfohlene Methode zum Durcharbeiten dieses Codelab. Sie können den Code auch klonen und in Ihrer bevorzugten Entwicklungsumgebung öffnen.
Öffnen Sie StackBlitz und führen Sie die App aus
Öffnen Sie dazu den Stackblitz-Link in Ihrem bevorzugten Webbrowser:
- Öffnen Sie einen neuen Browsertab und rufen Sie https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service.massage.ts auf.
- Erstellen Sie mithilfe von StackBlitz Ihren eigenen bearbeitbaren Arbeitsbereich. Stackblitz sollte die App automatisch ausführen und Sie können loslegen.
Alternative: Repository klonen und Anwendung bereitstellen
Eine alternative Methode zum Durcharbeiten dieses Codelabs ist die Verwendung von VSCode oder einer lokalen IDE:
- Öffnen Sie einen neuen Browsertab und rufen Sie https://github.com/angular/codelabs/tree/signals-get-started auf.
- Verzweigen und klonen Sie das Repository und verwenden Sie den Befehl
cd codelabs/
, um in das Repository zu wechseln. - Sehen Sie sich den Startcode-Branch mit dem Befehl
git checkout signals-get-started
an. - Öffnen Sie den Code in VSCode oder Ihrer bevorzugten IDE.
- Verwenden Sie den Befehl
npm install
, um die Abhängigkeiten zu installieren, die zum Ausführen des Servers erforderlich sind. - Führen Sie den Server mit dem Befehl
ng serve
aus. - Öffnen Sie einen Browsertab mit http://localhost:4200.
3. Baseline festlegen
Dein Ausgangspunkt ist ein Spiel „Angular Cipher“, aber es funktioniert noch nicht. Angular-Signale unterstützen die Funktionen des Spiels.
Sehen Sie sich zuerst die fertige Version von Angular Signals Cypher an.
- Sehen Sie sich die codierte Nachricht auf dem Bildschirm an.
- Ziehen Sie eine Buchstabentaste auf der Tastatur, um die Chiffre aufzulösen und die geheime Nachricht zu entschlüsseln.
- Prüfen Sie bei Erfolg, wie die Nachricht aktualisiert wird, um einen größeren Teil der geheimen Nachricht zu entschlüsseln.
- Klicken Sie auf Anpassen, um den Absender und die Nachricht zu ändern. Klicken Sie dann auf Erstellen und URL kopieren, um die Werte auf dem Bildschirm zu sehen und die URL zu ändern.
- Bonus: Kopieren Sie die URL und fügen Sie sie in einen neuen Tab ein oder teilen Sie sie mit einem Freund und sehen Sie, wie Absender und Nachricht in der URL gespeichert sind.
4. Erstes Signal() definieren
Ein Signal ist ein Wert, der Angular mitteilen kann, wenn es sich ändert. Einige Signale können direkt geändert werden, während andere ihre Werte aus den Werten anderer Signale berechnen. Gemeinsam erstellen Signale einen gerichteten Graphen von Abhängigkeiten, der den Datenfluss in Ihrer App modelliert.
Angular kann die Benachrichtigungen von Signalen verwenden, um zu erfahren, welche Komponenten geändert werden müssen, oder um von Ihnen definierte effect-Funktionen auszuführen.
superSecretMessage
in signal()
konvertieren
superSecretMessage
ist ein Wert in MessageService
, der die geheime Nachricht definiert, die der Spieler decodiert. Derzeit benachrichtigt der Wert die App nicht über Änderungen, daher ist die Schaltfläche Anpassen fehlerhaft. Sie können dieses Problem mithilfe eines Signals beheben.
Wenn du „superSecretMessage
“ als Signal festlegst, kannst du Teile der App benachrichtigen, die davon abhängen, wann die Nachricht geändert wurde. Wenn Sie die Mitteilung in einem Dialogfeld anpassen, legen Sie das Signal fest, dass der Rest der App mit der neuen Mitteilung aktualisiert wird.
Führen Sie zum Definieren des ersten Signals in jeder Datei die folgenden Schritte unter dem Kommentar TODO(1): Define your first signal()
aus:
- Verwenden Sie in der Datei
service.message.ts
die Signalbibliothek, umsuperSecretMessage
zu reaktiv zu machen:
src/app/secret-message/service.message.ts
superSecretMessage = signal(
'Angular Signals are in developer preview in v16 today!'
);
Dadurch werden Sie automatisch aufgefordert, signal
aus @angular/core
zu importieren. Wenn Sie die Seite aktualisieren, treten wahrscheinlich Fehler auf, bei denen Sie zuvor auf superSecretMessage
verwiesen haben. Das liegt daran, dass Sie den Typ von superSecretMessage
von string
zu SettableSignal<string>
geändert haben. Sie können das Problem beheben, indem Sie alle Referenzen von superSecretMessage
so ändern, dass die Signals API verwendet wird. Wann immer Sie den Wert lesen, sollten Sie den Signal Getter superSecretMessage()
aufrufen. Und wenn Sie den Wert schreiben, verwenden Sie die .set
API auf SettableSignal
, um den neuen Wert für die Nachricht festzulegen.
- Aktualisieren Sie in den Dateien
secret-message.ts
undservice.message.ts
alle Verweise vonsuperSecretMessage
aufsuperSecretMessage()
:
src/app/secret-message/secret-message.ts
// Before
this.messages.superSecretMessage
this.messages.superSecretMessage = message;
// After
this.messages.superSecretMessage()
this.messages.superSecretMessage.set(message);
src/app/secret-message/service.message.ts
// Before
this.superSecretMessage
// After
this.superSecretMessage()
Die beiden anderen Signale untersuchen
- In Ihrer App gibt es zwei weitere Signale:
src/app/cipher/service.cipher.ts
cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);
CipherService
definiert ein cipher
-Signal, eine zufällig generierte Zuordnung von Schlüssel/Wert-Paaren eines Buchstabens des Alphabets zu einem neuen cipher
-Buchstaben. Hiermit können Sie die Nachricht durchmischen und feststellen, ob der Spieler auf der Tastatur ein erfolgreiches Spiel findet.
Außerdem hast du ein decodedCipher
-Signal der erfolgreich decodierten Schlüssel/Wert-Paare, die du hinzufügen musst, wenn der Spieler die Chiffre löst.
Ein einzigartiges und leistungsstarkes Merkmal der Signalbibliothek von Angular besteht darin, dass Sie überall Reaktivität einführen können. Sie haben Signale einmal in den Diensten der App definiert. Sie können sie in einer Vorlage, Komponenten, Pipes, anderen Diensten oder überall dort verwenden, wo Sie Anwendungscode schreiben können. Sie sind nicht an einen Komponentenbereich beschränkt oder gebunden.
Änderungen überprüfen
- Sie müssen noch einen Schritt ausführen, bevor die App funktioniert. Versuche vorerst, in verschiedenen Bereichen deiner App eine
console.log()
hinzuzufügen, um zu sehen, wie dein neuessuperSecretMessage
eingerichtet wird.
5. Definieren Sie Ihr erstes „computed()“
In vielen Situationen kann es vorkommen, dass Sie den Zustand von vorhandenen Werten ableiten. Es ist besser, den abgeleiteten Status zu aktualisieren, wenn sich der abhängige Wert ändert.
Mit computed()
können Sie ein Signal deklarativ ausdrücken, das seinen Wert von anderen Signalen ableitet.
solvedMessage
in computed()
konvertieren
solvedMessage
wandelt den secretMessage
-Wert mithilfe des decodedCipher
-Signals vom codierten in den decodierten Wert um.
Das ist besonders praktisch, da Sie sehen, dass Sie ein berechnetes Ergebnis auf der Grundlage eines anderen berechneten. Jedes Mal, wenn sich ein Signal in diesem zugeordneten reaktiven Kontext ändert, werden die Abhängigkeiten benachrichtigt.
Derzeit wird der solvedMessage
nicht aktualisiert, wenn du secretMessage
, decodedCipher
oder superSecretMessage
änderst. Es werden also keine Aktualisierungen auf dem Bildschirm angezeigt, wenn der Spieler die Chiffre löst.
Wenn Sie solvedMessage
als berechnet festlegen, erstellen Sie einen reaktiven Kontext, sodass Sie die Statusaktualisierung aus den erfassten Abhängigkeiten ableiten können, wenn Sie die Nachricht aktualisieren oder die Chiffre ermitteln.
Führen Sie die folgenden Schritte unter dem Kommentar TODO(2): Define your first computed()
in jeder Datei aus, um solvedMessage
in computed()
zu konvertieren:
- Verwenden Sie in der Datei
service.message.ts
die Signalbibliothek, umsolvedMessage
reaktiv zu machen:
src/app/secret-message/service.message.ts
solvedMessage = computed(() =>
this.translateMessage(
this.secretMessage(),
this.cipher.decodedCipher()
)
);
Dadurch werden Sie automatisch aufgefordert, computed
aus @angular/core
zu importieren. Wenn Sie die Seite aktualisieren, treten wahrscheinlich Fehler auf, bei denen Sie zuvor auf solvedMessage
verwiesen haben. Das liegt daran, dass Sie den Typ der Funktion superSecretMessage
von string
in die Funktion Signal<string>
geändert haben. Sie können dieses Problem beheben, indem Sie alle Verweise von solvedMessage
in solvedMessage()
ändern.
- Aktualisieren Sie in der Datei
secret-message.ts
alle Verweise vonsolvedMessage
aufsolvedMessage()
:
src/app/secret-message/secret-message.ts
// Before
<span *ngFor="let char of this.messages.solvedMessage.split(''); index as i;" [class.unsolved]="this.messages.solvedMessage[i] !== this.messages.superSecretMessage()[i]" >{{ char }}</span>
// After
<span *ngFor="let char of this.messages.solvedMessage().split(''); index as i;" [class.unsolved]="this.messages.solvedMessage()[i] !== this.messages.superSecretMessage()[i]" >{{ char }}</span>
Im Gegensatz zu superSecretMessage
ist solvedMessage
keine SettableSignal
. Sie können den Wert nicht direkt ändern. Stattdessen wird der Wert jedes Mal aktualisiert, wenn eines der Abhängigkeitssignale (secretMessage
oder decodedCipher
) aktualisiert wird.
Die beiden anderen computed()
-Funktionen erkunden
- Beachten Sie, dass in Ihrer Anwendung zwei weitere berechnete Werte vorhanden sind:
src/app/secret-message/service.message.ts
secretMessage = computed(() =>
this.translateMessage(
this.superSecretMessage(),
this.cipher.cipher()
)
);
src/app/cipher/service.cipher.ts
unsolvedAlphabet = computed(() =>
ALPHABET.filter(
(letter) => !this.decodedCipher().find((guess) => guess.value === letter)
)
);
Mit MessageService
wird eine berechnete secretMessage
definiert, d. h. die superSecretMessage
, codiert durch die cipher
, die Spieler lösen müssen.
Mit CipherService
wird eine berechnete unsolvedAlphabet
definiert, d. h. eine Liste aller Buchstaben, die der Spieler nicht gelöst hat und die aus der Liste der aufgelösten Verschlüsselungsschlüssel in decodedCipher
abgeleitet wird.
Änderungen überprüfen
Da superSecretMessage
jetzt ein Signal und solvedMessage
ein berechneter Wert ist, sollte die App funktionieren. Funktionen des Spiels testen:
- Ziehe eine
LetterGuessComponent
per Drag-and-drop auf eineLetterKeyComponent
in deinemCipherComponent
, um die Chiffre zu lösen und die geheime Nachricht zu entschlüsseln. - Sehen Sie sich an, wie
SecretMessageComponent
aktualisiert wird, wenn Sie mehr der geheimen Nachricht entschlüsseln. - Klicken Sie auf Anpassen, um den Absender und die Nachricht zu ändern. Klicken Sie dann auf Erstellen und URL kopieren, um die Werte auf dem Bildschirm zu sehen und die URL zu ändern.
- Bonus: Kopieren Sie die URL und fügen Sie sie in einen neuen Tab ein oder teilen Sie sie mit einem Freund und sehen Sie, wie Absender und Nachricht in der URL gespeichert sind.
6. Füge deine erste Auswirkung() hinzu.
Manchmal soll etwas passieren, wenn ein Signal einen neuen Wert hat. Mit effect()
können Sie eine Handler-Funktion planen und ausführen, wenn sich die Signale ändern.
Konfetti hinzufügen, wenn die Chiffre gelöst ist
Jetzt, da die App funktioniert, kannst du für noch mehr Spaß Konfetti hinzufügen, sobald die Chiffre gelöst und die geheime Nachricht entschlüsselt wurde.
Führe die folgenden Schritte unter dem Kommentar „TODO(3): Add your first effect()
“ aus, um Konfetti hinzuzufügen:
- Legen Sie in der Datei
cipher.ts
einen Effekt fest, um Konfetti hinzuzufügen, wenn die Nachricht decodiert wird:
src/app/cipher/cipher.ts
import * as confetti from 'canvas-confetti';
ngOnInit(): void {
...
effect(() => {
if (this.messages.superSecretMessage() === this.messages.solvedMessage()) {
var confettiCanvas = document.getElementById('confetti-canvas');
confetti.create()(confettiCanvas, { particleCount: 100 });
}
});
}
Beachten Sie, wie dieser Effekt von einem Signal und einem berechneten Wert abhängt: this.messages.superSecretMessage()
und this.messages.solvedMessage()
.
Mit dem Effekt „Effekt“ können Sie die Konfettifunktion in einem reaktiven Kontext planen, um sie zu verfolgen und neu zu bewerten, wenn ihre Abhängigkeiten aktualisiert werden.
Änderungen überprüfen
- Versuche, die Chiffre zu lösen (Tipp: Du kannst die Nachricht in eine Kurzform ändern, um schneller zu testen!). Zum ersten
effect()
gratuliert dir ein Konfetti-Pop!
7. Glückwunsch!
Deine Angular Cipher ist jetzt bereit, geheime Nachrichten zu decodieren und zu teilen! Hast du eine Nachricht für das Angular-Team? Tagge unsere sozialen Medien unter @Angular, damit wir sie decodieren können! 🎉
In deiner Angular-Toolbox findest du jetzt drei neue reaktive Primitive, mit denen du die Entwicklung vereinfachen und standardmäßig schnellere Apps erstellen kannst.
Weitere Informationen
Dann sieh dir diese Codelabs an:
Lesen Sie diese Materialien:
- Angular.io
- Rethinking Reactivity with Signals (Google I/O 2023)
- Das ist neu bei Angular (Google I/O 2023)