1. Hinweis

Mit Angular Signals werden drei reaktive Primitive in Angular eingeführt, die die Entwicklung vereinfachen und Ihnen helfen, standardmäßig schnellere Apps zu erstellen.
Umfang
- Sie lernen die drei reaktiven Primitiven kennen, die mit Angular Signals eingeführt wurden:
signal(),computed()undeffect(). - Angular Signals für ein Angular Cipher-Spiel verwenden Chiffren sind Systeme zum Ver- 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. Außerdem können sie die Nachricht anpassen und die URL teilen, um Freunden geheime Nachrichten zu senden.

Voraussetzungen
- Kenntnisse von 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, ist in einem Stackblitz enthalten. Stackblitz ist die empfohlene Methode für dieses Codelab. Alternativ können Sie den Code klonen und in Ihrer bevorzugten Entwicklungsumgebung öffnen.
Stackblitz öffnen und App ausführen
Öffnen Sie 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.
- Forken Sie den StackBlitz, um einen eigenen bearbeitbaren Arbeitsbereich zu erstellen. Stackblitz sollte die App automatisch ausführen.
Alternative: Repository klonen und App bereitstellen
Die Verwendung von VS Code oder einer lokalen IDE ist eine alternative Methode, um dieses Codelab durchzuarbeiten:
- Öffnen Sie einen neuen Browsertab und rufen Sie https://github.com/angular/codelabs/tree/signals-get-started auf.
- Führen Sie einen Fork und Klon des Repositorys aus und verwenden Sie den Befehl
cd codelabs/, um in das Repository zu wechseln. - Sehen Sie sich den Branch mit dem Startcode mit dem Befehl
git checkout signals-get-startedan. - Öffnen Sie den Code in VSCode oder Ihrer bevorzugten IDE.
- Verwenden Sie den Befehl
npm install, um die zum Ausführen des Servers erforderlichen Abhängigkeiten zu installieren. - Verwenden Sie den Befehl
ng serve, um den Server auszuführen. - Öffnen Sie einen Browsertab für http://localhost:4200.
3. Baseline festlegen
Sie haben ein Angular Cipher-Spiel als Ausgangspunkt, aber es funktioniert noch nicht. Angular Signals werden die Funktionalität des Spiels unterstützen.

Sehen Sie sich zuerst die fertige Version des Projekts an, das Sie erstellen werden: Angular Signals Cypher.
- Sehen Sie sich die codierte Nachricht auf dem Bildschirm an.
- Ziehen Sie eine Buchstabenschaltfläche auf das Tastenfeld, um die Chiffre zu knacken und die geheime Nachricht zu entschlüsseln.
- Bei Erfolg wird die Nachricht aktualisiert, um mehr von der geheimen Nachricht zu entschlüsseln.
- Klicken Sie auf Anpassen, um Absender und Mitteilung zu ändern, und dann auf URL erstellen und kopieren, um die Werte auf dem Bildschirm und die Änderung der URL zu sehen.
- Bonus: Kopieren Sie die URL und fügen Sie sie in einen neuen Tab ein oder teilen Sie sie mit einem Freund. So können Sie sehen, wie Absender und Nachricht in der URL gespeichert werden.

4. Erstes Signal() definieren
Ein Signal ist ein Wert, der Angular mitteilen kann, wann er sich ändert. Einige Signale können direkt geändert werden, während die Werte anderer Signale aus den Werten anderer Signale berechnet werden. Zusammen bilden Signale einen gerichteten Abhängigkeitsgraphen, der den Datenfluss in Ihrer App modelliert.
Angular kann anhand der Benachrichtigungen von Signalen erkennen, bei welchen Komponenten eine Änderungserkennung erforderlich ist oder welche von Ihnen definierten Effektfunktionen ausgeführt werden müssen.
superSecretMessage in ein signal() konvertieren
superSecretMessage ist ein Wert in MessageService, der die geheime Nachricht definiert, die der Spieler entschlüsselt. Derzeit werden Änderungen nicht an die App gemeldet, daher funktioniert die Schaltfläche Anpassen nicht. Sie können dieses Problem mit einem Signal beheben.
Wenn Sie superSecretMessage zu einem Signal machen, können Sie Teile der App benachrichtigen, die darauf angewiesen sind, wenn sich die Nachricht ändert. Wenn Sie die Nachricht in einem Dialogfeld anpassen, wird das Signal festgelegt, um den Rest der App mit der neuen Nachricht zu aktualisieren.
Gehen Sie so vor, um Ihr erstes Signal zu definieren:TODO(1): Define your first signal()
- Verwenden Sie in der Datei
service.message.tsdie Signals-Bibliothek, umsuperSecretMessagereaktiv zu machen:
src/app/secret-message/service.message.ts
superSecretMessage = signal(
'Angular Signals are in developer preview in v16 today!'
);
Sie werden dann 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 überall dort, wo Sie den Wert lesen, den Signal-Getter superSecretMessage() auf. Verwenden Sie die .set API für SettableSignal, um den neuen Wert für die Nachricht festzulegen.
- Aktualisieren Sie in den Dateien
secret-message.tsundservice.message.tsalle Verweise vonsuperSecretMessagezusuperSecretMessage():
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 ansehen
- Beachten Sie, dass Sie zwei weitere Signale in Ihrer App haben:
src/app/cipher/service.cipher.ts
cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);
Mit CipherService wird ein cipher-Signal definiert, eine zufällig generierte Zuordnung von Schlüssel/Wert-Paaren eines Buchstabens des Alphabets zu einem neuen cipher-Buchstaben. Damit wird die Nachricht verschlüsselt und es wird ermittelt, ob der Spieler auf der Tastatur eine Übereinstimmung findet.
Außerdem haben Sie ein decodedCipher-Signal der erfolgreich decodierten Schlüssel/Wert-Paare, das Sie ergänzen, wenn der Spieler die Chiffre löst.
Ein einzigartiges und leistungsstarkes Attribut des Designs der Signals-Bibliothek von Angular ist, dass Sie überall Reaktivität einführen können. Sie haben Signale einmal in den Diensten der App definiert und können sie in einer Vorlage, Komponenten, Pipes, anderen Diensten oder überall dort verwenden, wo Sie Anwendungscode schreiben können. Sie sind nicht auf einen Komponentenbereich beschränkt.
Änderungen bestätigen
- Es ist noch ein Schritt erforderlich, bevor die App funktioniert. Fügen Sie vorerst ein
console.log()an verschiedenen Stellen in Ihrer App ein, um zu sehen, wie Ihr neuessuperSecretMessagefestgelegt wird.

5. Erste computed() definieren
In vielen Situationen leiten Sie den Status aus vorhandenen Werten ab. Es ist besser, wenn der abgeleitete Status aktualisiert wird, wenn sich der abhängige Wert ändert.
Mit computed() können Sie deklarativ ein Signal ausdrücken, dessen Wert von anderen Signalen abgeleitet wird.
solvedMessage in ein computed() konvertieren
Mit solvedMessage wird der secretMessage-Wert mithilfe des decodedCipher-Signals von codiert in decodiert übersetzt.
Das ist besonders praktisch, weil Sie sehen können, dass ein berechneter Wert auf einem anderen berechneten Wert basiert. Wenn sich also ein Signal im zugeordneten reaktiven Kontext ändert, werden die Abhängigkeiten benachrichtigt.
Derzeit wird solvedMessage nicht aktualisiert, wenn Sie secretMessage, decodedCipher oder superSecretMessage ändern. Daher werden keine Aktualisierungen auf dem Bildschirm angezeigt, wenn der Spieler die Chiffre löst.
Wenn Sie solvedMessage zu einer berechneten Eigenschaft machen, erstellen Sie einen reaktiven Kontext. Wenn Sie also die Nachricht aktualisieren oder die Chiffre lösen, können Sie den Status aus den verfolgten 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.tsdie Signals-Bibliothek, umsolvedMessagereaktiv zu machen:
src/app/secret-message/service.message.ts
solvedMessage = computed(() =>
this.translateMessage(
this.secretMessage(),
this.cipher.decodedCipher()
)
);
Sie werden dann automatisch aufgefordert, computed aus @angular/core zu importieren. Wenn Sie die Seite aktualisieren, treten wahrscheinlich Fehler auf, wenn Sie zuvor auf solvedMessage verwiesen haben. Das liegt daran, dass Sie den Typ von superSecretMessage von string in Signal<string>, eine Funktion, geändert haben. Sie können das Problem beheben, indem Sie alle Verweise auf solvedMessage in solvedMessage() ändern.
- Aktualisieren Sie in der Datei
secret-message.tsalle Verweise vonsolvedMessageaufsolvedMessage():
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 immer dann aktualisiert, wenn eines der zugehörigen Abhängigkeitssignale (secretMessage und decodedCipher) aktualisiert wird.
Die beiden anderen computed()-Funktionen kennenlernen
- Beachten Sie, dass Ihre App zwei weitere berechnete Werte enthält:
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 secretMessage, die superSecretMessage ist und von der cipher codiert wird. Spieler müssen sie lösen.
Mit CipherService wird eine berechnete unsolvedAlphabet definiert, eine Liste aller Buchstaben, die der Spieler noch nicht entschlüsselt hat. Diese Liste wird aus der Liste der entschlüsselten Chiffrierschlüssel in decodedCipher abgeleitet.
Änderungen bestätigen
Da superSecretMessage jetzt ein Signal und solvedMessage ein berechneter Wert ist, sollte die App funktionieren. Funktionen des Spiels testen:
- Ziehen Sie ein
LetterGuessComponentper Drag-and-drop auf einLetterKeyComponentin IhremCipherComponent, um die Chiffre zu knacken und die geheime Nachricht zu entschlüsseln. - Sehen Sie, wie sich die
SecretMessageComponentändert, wenn Sie weitere Teile der geheimen Nachricht entschlüsseln. - Klicken Sie auf Anpassen, um Absender und Mitteilung zu ändern, und dann auf URL erstellen und kopieren, um die Werte auf dem Bildschirm und die Änderung der URL zu sehen.
- Bonus: Kopieren Sie die URL und fügen Sie sie in einen neuen Tab ein oder teilen Sie sie mit einem Freund. So können Sie sehen, wie Absender und Nachricht in der URL gespeichert werden.

6. Ersten effect() hinzufügen
Es kann vorkommen, dass Sie möchten, dass etwas passiert, wenn ein Signal einen neuen Wert hat. Mit effect() können Sie eine Handler-Funktion planen und ausführen, wenn sich Signale ändern.
Konfetti hinzufügen, wenn das Chiffre gelöst ist
Nachdem die App funktioniert, können Sie sie noch etwas aufpeppen, indem Sie Konfetti hinzufügen, wenn das Chiffrat gelöst und die geheime Nachricht entschlüsselt wird.
Führen Sie die folgenden Schritte aus, um Konfetti hinzuzufügen:TODO(3): Add your first effect()
- Planen Sie in der Datei
cipher.tseinen Effekt, 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 });
}
});
}
Dieser Effekt hängt von einem Signal und einem berechneten Wert ab: this.messages.superSecretMessage() und this.messages.solvedMessage().
Mit „Effect“ können Sie die Konfettifunktion in einem reaktiven Kontext planen, um zu verfolgen und neu zu bewerten, wann ihre Abhängigkeiten aktualisiert werden.
Änderungen bestätigen
- Versuchen Sie, die Chiffre zu lösen. Tipp: Sie können die Nachricht in etwas Kurzes ändern, um schneller zu testen. Ein Konfetti-Pop-up gratuliert dir zu deinem ersten
effect().

7. Glückwunsch!
Ihr Angular-Chiffre ist jetzt bereit, um geheime Nachrichten zu entschlüsseln und zu teilen. Haben Sie eine Nachricht für das Angular-Team? Taggen Sie uns in den sozialen Medien mit @Angular, damit wir es entschlüsseln können. 🎉

Es gibt jetzt drei neue reaktive Primitives in Ihrem Angular-Toolkit, mit denen Sie die Entwicklung vereinfachen und standardmäßig schnellere Apps erstellen können.
Weitere Informationen
Sehen Sie sich diese Codelabs an:
Lesen Sie sich diese Materialien durch:
- Angular.io
- Reaktivität mit Signalen neu denken (Google I/O 2023)
- What's new in Angular (Google I/O 2023)