1. Prima di iniziare
Angular Signals introduce tre primitive reattive per Angular che conosci e ami, semplificando il tuo sviluppo e aiutandoti a creare app più veloci per impostazione predefinita.
Cosa creerai
- Scoprirai le tre primitive reattive introdotte con gli indicatori Angular:
signal()
,computed()
eeffect()
. - Usa i segnali Angular per creare un gioco Angular Cipher. Le crittografie sono sistemi per la crittografia e la decriptazione dei dati. In questo gioco, gli utenti possono decodificare un messaggio segreto trascinando indizi per risolvere la crittografia, personalizzare il messaggio e condividere l'URL per inviare messaggi segreti agli amici.
Prerequisiti
- Conoscenza di Angular e TypeScript
- Consigliato: guarda Rethinking Reactivity with Signals per saperne di più sulla raccolta Angular Signals
2. Ottieni il codice
Tutto ciò di cui hai bisogno per questo progetto è in uno Stackblitz. Stackblitz è il metodo consigliato per seguire questo codelab. In alternativa, clona il codice e aprilo nel tuo ambiente di sviluppo preferito.
Apri Stackblitz ed esegui l'app.
Per iniziare, apri il link Stackblitz nel tuo browser web preferito:
- Apri una nuova scheda del browser e vai a https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service.massage.ts
- Crea un fork di Stackblitz per creare la tua area di lavoro modificabile. Stackblitz dovrebbe eseguire automaticamente l'app ed è tutto pronto per iniziare.
Alternativa: clona il repository e pubblica l'app
L'utilizzo di VSCode o di un IDE locale è un metodo alternativo per seguire questo codelab:
- Apri una nuova scheda del browser e vai a https://github.com/angular/codelabs/tree/signals-get-started.
- Crea un fork e clona il repository e usa il comando
cd codelabs/
per spostarlo nel repository. - Controlla il ramo del codice di avvio con il comando
git checkout signals-get-started
. - Apri il codice in VSCode o nel tuo IDE preferito.
- Per installare le dipendenze necessarie per eseguire il server, usa il comando
npm install
. - Per eseguire il server, utilizza il comando
ng serve
. - Apri una scheda del browser all'indirizzo http://localhost:4200.
3. Stabilisci una base di riferimento
Il tuo punto di partenza è un gioco Angular Cipher, ma non funziona ancora. Gli indicatori angolari alimenteranno le funzionalità del gioco.
Per iniziare, esamina la versione completa di ciò che stai creando: Angular Signals Cypher.
- Visualizza il messaggio codificato sullo schermo.
- Trascina il pulsante di una lettera sul tastierino per risolvere il problema di crittografia e decodificare il messaggio segreto.
- Se l'operazione riesce, osserva come viene aggiornato il messaggio per decodificare un numero maggiore di messaggi secret.
- Fai clic su Personalizza per modificare Mittente e messaggio, quindi fai clic su Crea e Copia URL per vedere i valori sullo schermo e l'URL cambiano.
- Bonus: copia e incolla l'URL in una nuova scheda oppure condividilo con un amico per vedere come il mittente e il messaggio sono memorizzati nell'URL.
4. Definisci il tuo primo indicatore()
Un indicatore è un valore che può indicare ad Angular quando cambia. Alcuni indicatori possono essere modificati direttamente, mentre altri calcolano i loro valori in base a quelli di altri indicatori. Insieme, gli indicatori creano un grafo diretto di dipendenze che modella il flusso di dati nell'app.
Angular può utilizzare le notifiche degli indicatori per sapere quali componenti devono essere rilevati dalla modifica o per eseguire le funzioni effect da te definite.
Converti superSecretMessage
in signal()
superSecretMessage
è un valore in MessageService
che definisce il messaggio segreto decodificato dal player. Attualmente, il valore non comunica all'app le modifiche apportate, pertanto il pulsante Personalizza non funziona. Puoi risolvere il problema con un indicatore.
Se imposti un segnale superSecretMessage
, puoi inviare notifiche alle parti dell'app che dipendono dalla conoscenza della modifica del messaggio. Quando personalizzi il messaggio in una finestra di dialogo, imposti l'indicatore per aggiornare il resto dell'app con il nuovo messaggio.
Per definire il primo indicatore, segui questi passaggi nel commento TODO(1): Define your first signal()
di ogni file:
- Nel file
service.message.ts
, utilizza la raccolta degli indicatori per rendere reattivosuperSecretMessage
:
src/app/secret-message/service.message.ts
superSecretMessage = signal(
'Angular Signals are in developer preview in v16 today!'
);
In questo modo ti viene chiesto automaticamente di importare signal
da @angular/core
. Se aggiorni la pagina, è probabile che si verifichino errori in cui in precedenza avevi fatto riferimento a superSecretMessage
. Questo perché hai modificato il tipo di superSecretMessage
da string
a SettableSignal<string>
. Puoi risolvere il problema modificando tutti i riferimenti di superSecretMessage
in modo che utilizzi l'API Signals. Ovunque leggi il valore, chiama il getter di indicatori superSecretMessage()
. Ogni volta che scrivi il valore, utilizza l'API .set
su SettableSignal
per impostare il nuovo valore per il messaggio.
- Nei file
secret-message.ts
eservice.message.ts
, aggiorna tutti i riferimenti disuperSecretMessage
insuperSecretMessage()
:
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()
Scopri gli altri due indicatori
- Nota che nella tua app sono presenti altri due indicatori:
src/app/cipher/service.cipher.ts
cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);
L'CipherService
definisce un indicatore cipher
, ovvero una mappatura generata in modo casuale di coppie chiave-valore di una lettera dell'alfabeto a una nuova lettera cipher
. Lo userai per mescolare il messaggio e determinare se il giocatore trova una corrispondenza riuscita sulla tastiera.
Hai anche un indicatore decodedCipher
delle coppie chiave-valore decodificate correttamente che aggiungerai man mano che il player risolve la crittografia.
Un attributo unico e potente del design della libreria degli indicatori di Angular è che puoi introdurre reattività ovunque. Hai definito gli indicatori una sola volta nei servizi dell'app e puoi utilizzarli in un modello, in componenti, in pipe, in altri servizi o ovunque sia possibile scrivere il codice dell'applicazione. Non sono limitate né vincolati a un ambito di un componente.
Verifica modifiche
- Devi eseguire un altro passaggio prima che l'app funzioni. Per il momento, prova ad aggiungere
console.log()
in diverse parti dell'app per vedere come viene impostato il nuovosuperSecretMessage
.
5. Definisci la tua prima funzione computed()
In molte situazioni potresti ricavare uno stato da valori esistenti. È preferibile aggiornare lo stato derivato quando il valore dipendente cambia.
Con computed()
, puoi esprimere in modo dichiarativo un indicatore che trae il suo valore da altri indicatori.
Converti solvedMessage
in computed()
solvedMessage
converte il valore secretMessage
da codificato a decodificato utilizzando il segnale decodedCipher
.
Questo è davvero fantastico perché puoi vedere che stai ricavando un calcolo basato su un altro calcolato, quindi ogni volta che un segnale all'interno di quel contesto reattivo mappato cambia, le dipendenze vengono notificate.
Al momento, l'solvedMessage
non viene aggiornato quando modifichi secretMessage
, decodedCipher
o superSecretMessage
. Di conseguenza, non si vedono gli aggiornamenti sullo schermo quando il player risolve la crittografia.
Se rendi il criterio solvedMessage
calcolato, crei un contesto reattivo in modo che, quando aggiorni il messaggio o risolvi la crittografia, puoi ricavare l'aggiornamento di stato dalle dipendenze monitorate.
Per convertire solvedMessage
in un computed()
, segui questi passaggi nel commento TODO(2): Define your first computed()
di ogni file:
- Nel file
service.message.ts
, utilizza la raccolta degli indicatori per rendere reattivosolvedMessage
:
src/app/secret-message/service.message.ts
solvedMessage = computed(() =>
this.translateMessage(
this.secretMessage(),
this.cipher.decodedCipher()
)
);
In questo modo ti viene chiesto automaticamente di importare computed
da @angular/core
. Se aggiorni la pagina, è probabile che si verifichino errori in cui in precedenza avevi fatto riferimento a solvedMessage
. Il motivo è che hai modificato il tipo di superSecretMessage
da string
a Signal<string>
, una funzione. Puoi risolvere il problema modificando tutti i riferimenti di solvedMessage
in solvedMessage()
.
- Nel file
secret-message.ts
, aggiorna tutti i riferimenti disolvedMessage
insolvedMessage()
:
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>
Tieni presente che, a differenza di superSecretMessage
, solvedMessage
non è un SettableSignal
e non puoi modificarne direttamente il valore. Il suo valore viene invece mantenuto aggiornato ogni volta che uno dei suoi indicatori di dipendenza (secretMessage
e decodedCipher
) viene aggiornato.
Esplora le altre due funzioni computed()
- Tieni presente che nella tua app sono presenti altri due valori calcolati:
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)
)
);
Il MessageService
definisce un secretMessage
calcolato, il superSecretMessage
codificato dal cipher
che i player devono risolvere.
Il parametro CipherService
definisce un valore unsolvedAlphabet
calcolato, ovvero un elenco di tutte le lettere non risolte dal player, che deriva dall'elenco di chiavi di crittografia risolte presenti in decodedCipher
.
Verifica modifiche
Ora che superSecretMessage
è un indicatore e solvedMessage
è calcolato, l'app dovrebbe funzionare. Prova le funzionalità del gioco:
- Trascina un
LetterGuessComponent
in unLetterKeyComponent
diCipherComponent
per risolvere il problema di crittografia e decodificare il messaggio segreto. - Scopri come
SecretMessageComponent
si aggiorna man mano che decodifica più messaggi segreti. - Fai clic su Personalizza per modificare Mittente e messaggio, quindi fai clic su Crea e Copia URL per vedere i valori sullo schermo e l'URL cambiano.
- Bonus: copia e incolla l'URL in una nuova scheda oppure condividilo con un amico per vedere come il mittente e il messaggio sono memorizzati nell'URL.
6. Aggiungi il tuo primo result()
A volte potresti volere che si verifichi qualcosa quando un indicatore ha un nuovo valore. Con effect()
, puoi pianificare ed eseguire una funzione gestore in risposta al cambiamento degli indicatori.
Aggiungere coriandoli quando la crittografia è risolta
Ora che l'app è funzionante, puoi aggiungere un tocco di divertimento aggiungendo dei coriandoli quando la crittografia è risolta e il messaggio segreto è stato decodificato.
Per aggiungere coriandoli, procedi nel seguente modo sotto il commento TODO(3): Add your first effect()
:
- Nel file
cipher.ts
, programma un effetto per aggiungere coriandoli quando il messaggio viene decodificato:
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 });
}
});
}
Nota come questo effetto dipende da un indicatore e da un valore calcolato: this.messages.superSecretMessage()
e this.messages.solvedMessage()
.
L'effetto ti aiuta a pianificare la funzione dei coriandoli all'interno di un contesto reattivo per monitorare e rivalutare quando le sue dipendenze vengono aggiornate.
Verifica modifiche
- Prova a risolvere la questione della crittografia (suggerimento: puoi cambiare il messaggio in qualcosa di breve per testarlo più rapidamente). Uno scoppiettante coriandoli si congratula con te per il tuo primo
effect()
!
7. Complimenti!
Il tuo Angular Cipher è ora pronto per decodificare e condividere messaggi segreti. Hai un messaggio per il team di Angular? Tagga i nostri social media su @Angular per consentirci di decodificarli. 🎉
Ora nel tuo toolbox Angular hai a disposizione tre nuove primitive reattive per semplificare lo sviluppo e creare app più veloci per impostazione predefinita.
Scopri di più
Dai un'occhiata a questi codelab:
Leggi questi materiali:
- Angular.io
- Ripensare la reattività con gli indicatori (Google I/O 2023)
- Novità di Angular (Google I/O 2023)