1. Hinweis
Mit Angular-Signalen werden drei reaktive Primitive in das bekannte und beliebte Angular eingeführt. So wird die Entwicklung vereinfacht und Sie können standardmäßig schneller Apps erstellen.
Umfang
- Sie erfahren mehr über die drei mit Angular Signals eingeführten reaktiven Primitiven:
signal()
,computed()
undeffect()
. - Angular-Signale für ein Angular-Chiffrenspiel verwenden Chiffren sind Systeme zum Verschlüsseln und Entschlüsseln von Daten. In diesem Spiel können Nutzer eine geheime Nachricht entschlüsseln, indem sie Hinweise per Drag-and-drop verschieben, 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: Sehen Sie sich Rethinking Reactivity with Signals an, um mehr über die Angular Signals-Bibliothek zu erfahren.
2. Code abrufen
Alles, was Sie für dieses Projekt benötigen, befindet sich in einem Stackblitz. Für dieses Codelab wird Stackblitz empfohlen. 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 zuerst 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 einen Fork des Stackblitz, um einen eigenen bearbeitbaren Arbeitsbereich zu erstellen. Die App sollte jetzt automatisch in Stackblitz ausgeführt werden.
Alternative: Repository klonen und Anwendung bereitstellen
Sie können dieses Codelab auch mit VSCode oder einer lokalen IDE durcharbeiten:
- Öffnen Sie einen neuen Browsertab und rufen Sie https://github.com/angular/codelabs/tree/signals-get-started auf.
- Erstellen Sie ein Fork und klonen Sie das Repository. Verschieben Sie sich dann mit dem Befehl
cd codelabs/
in das Repository. - Rufen Sie den Startcode-Branch mit dem Befehl
git checkout signals-get-started
ab. - Öffnen Sie den Code in VS Code oder Ihrer bevorzugten IDE.
- Verwenden Sie den Befehl
npm install
, um die Abhängigkeiten zu installieren, die zum Ausführen des Servers erforderlich sind. - Verwenden Sie den Befehl
ng serve
, um den Server auszuführen. - Öffnen Sie einen Browsertab und rufen Sie http://localhost:4200 auf.
3. Baseline festlegen
Dein Ausgangspunkt ist ein Spiel „Angular Cipher“, aber es funktioniert noch nicht. Angular-Signale steuern die Funktionalität des Spiels.
Sehen Sie sich zuerst die fertige Version des Projekts an, das Sie erstellen werden: Angular Signals Cypher.
- Rufen Sie die codierte Nachricht auf dem Bildschirm auf.
- Ziehen Sie eine Buchstabentaste per Drag-and-drop auf die Tastatur, um die Chiffre zu knacken 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 URL erstellen und 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. Zusammen bilden die Signale einen gerichteten Abhängigkeitsgraphen, 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 mit einem Signal lösen.
Wenn Sie superSecretMessage
als Signal festlegen, können Sie Teile der App benachrichtigen, die wissen müssen, wann sich die Nachricht geändert hat. Wenn Sie die Nachricht in einem Dialogfeld anpassen, legen Sie das Signal fest, um den Rest der App mit der neuen Nachricht zu aktualisieren.
So definieren Sie das erste Signal: Gehen Sie in jeder Datei unter dem Kommentar TODO(1): Define your first signal()
so vor:
- Verwenden Sie in der Datei
service.message.ts
die Signalbibliothek, umsuperSecretMessage
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, wenn Sie zuvor auf superSecretMessage
verwiesen haben. Das liegt daran, dass Sie den Typ von superSecretMessage
von string
in SettableSignal<string>
geändert haben. Sie können das Problem beheben, indem Sie alle Verweise auf superSecretMessage
so ändern, dass die Signals API verwendet wird. Rufen Sie den Signalgetter superSecretMessage()
an, wo immer Sie den Wert lesen. Überall dort, wo du den Wert schreibst, verwende 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 aufsuperSecretMessage
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
- Beachten Sie, dass Sie in Ihrer App zwei weitere Signale haben:
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 des Signals-Bibliotheksdesigns von Angular ist, 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, in Komponenten, Pipes, in anderen Diensten oder überall dort verwenden, wo Sie Anwendungscode schreiben können. Sie sind nicht auf einen Komponentenbereich beschränkt oder gebunden.
Änderungen prüfen
- Sie müssen noch einen Schritt ausführen, damit 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 Fällen müssen Sie den Status aus vorhandenen Werten ableiten. Es ist besser, wenn der abgeleitete Status aktualisiert wird, wenn sich der abhängige Wert ändert.
Mit computed()
können Sie ein Signal deklarativ ausdrücken, dessen Wert aus anderen Signalen abgeleitet wird.
solvedMessage
in computed()
konvertieren
solvedMessage
übersetzt den secretMessage
-Wert mithilfe des decodedCipher
-Signals von codiert zu decodiert.
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 die 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. Wenn Sie die Nachricht aktualisieren oder die Chiffre lösen, können Sie den Status aus den erfassten Abhängigkeiten ableiten.
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 Signals-Bibliothek, 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 von superSecretMessage
von string
in Signal<string>
geändert haben, eine Funktion. 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 aufsolvedMessage
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 also nicht direkt ändern. Stattdessen wird der Wert immer aktualisiert, wenn eines der Abhängigkeitssignale (secretMessage
und decodedCipher
) aktualisiert wird.
Die beiden anderen computed()
-Funktionen kennenlernen
- 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)
)
);
Die MessageService
definiert eine berechnete secretMessage
, die superSecretMessage
, die vom cipher
codiert wird und die Spieler lösen müssen.
Die CipherService
definiert eine berechnete unsolvedAlphabet
, eine Liste aller Buchstaben, die der Spieler noch nicht gelöst hat. Diese Liste wird aus der Liste der gelösten Geheimschlüssel in decodedCipher
abgeleitet.
Änderungen prüfen
Da superSecretMessage
jetzt ein Signal und solvedMessage
ein berechneter Wert ist, sollte die App funktionieren. Testen Sie die Funktionen des Spiels:
- Ziehen Sie eine
LetterGuessComponent
per Drag-and-drop auf eineLetterKeyComponent
in IhrerCipherComponent
, um die Chiffre zu knacken und die geheime Nachricht zu entschlüsseln. - Sehen Sie sich an, wie
SecretMessageComponent
aktualisiert wird, wenn Sie mehr der geheimen Nachricht decodieren. - Klicken Sie auf Anpassen, um den Absender und die Nachricht zu ändern. Klicken Sie dann auf URL erstellen und 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.
In bestimmten Fällen möchten Sie vielleicht, dass ein Signal einen neuen Wert hat. Mit effect()
können Sie eine Handlerfunktion planen und ausführen, wenn sich Signale ändern.
Konfetti hinzufügen, wenn die Chiffre gelöst wurde
Jetzt, da die App funktioniert, können Sie sie noch etwas unterhaltsamer gestalten, indem Sie Konfetti hinzufügen, wenn die Chiffre gelöst und die geheime Nachricht decodiert 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, dass dieser Effekt von einem Signal und einem berechneten Wert abhängt: this.messages.superSecretMessage()
und this.messages.solvedMessage()
.
Mit „Effekt“ kannst du die Konfettifunktion in einem reaktiven Kontext planen, um zu verfolgen und neu zu bewerten, wann ihre Abhängigkeiten aktualisiert werden.
Änderungen prüfen
- Versuchen Sie, die Chiffre zu entschlüsseln. Hinweis: Sie können die Nachricht in einen kurzen Text ändern, um den Test schneller durchzuführen. Du wirst mit Konfetti beglückwünscht.
effect()
7. Glückwunsch!
Deine Angular Cipher ist jetzt bereit, geheime Nachrichten zu decodieren und zu teilen! Haben Sie eine Nachricht für das Angular-Team? Taggen Sie uns in den sozialen Medien unter @Angular, damit wir es entschlüsseln können. 🎉
Sie haben jetzt drei neue reaktive Primitive in Ihrer Angular-Toolbox, mit denen Sie die Entwicklung vereinfachen und standardmäßig schnellere Apps erstellen können.
Weitere Informationen
Sehen Sie sich diese Codelabs an:
Lesen Sie die folgenden Materialien:
- Angular.io
- Reaktivität mithilfe von Signalen neu überdenken (Google I/O 2023)
- Neuerungen in Angular (Google I/O 2023)