Inizia a utilizzare gli indicatori Angular

1. Prima di iniziare

logo Angular nero

Angular Signals introduce tre primitive reattive in Angular, che conosci e ami, semplificando lo sviluppo e aiutandoti a creare app più veloci per impostazione predefinita.

Cosa creerai

  • Scopri le tre primitive reattive introdotte con Angular Signals: signal(), computed() e effect().
  • Utilizza Angular Signals per potenziare un gioco di crittografia Angular. I sistemi di crittografia sono sistemi per criptare e decriptare i 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.

Gioco di crittografia angolare nello stile di una console da gioco verde vintage, con un messaggio nascosto sullo schermo "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

Prerequisiti

2. Ottieni il codice

Tutto ciò che ti serve per questo progetto si trova in un Stackblitz. Stackblitz è il metodo consigliato per svolgere 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 a Stackblitz nel tuo browser web preferito:

  1. 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
  2. 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 svolgere questo codelab:

  1. Apri una nuova scheda del browser e vai a https://github.com/angular/codelabs/tree/signals-get-started.
  2. Crea un fork e clona il repository, quindi utilizza il comando cd codelabs/ per spostarti nel repository.
  3. Controlla il ramo del codice di avvio con il comando git checkout signals-get-started.
  4. Apri il codice in VSCode o nel tuo IDE preferito.
  5. Per installare le dipendenze necessarie per l'esecuzione del server, utilizza il comando npm install.
  6. Per eseguire il server, utilizza il comando ng serve.
  7. Apri una scheda del browser all'indirizzo http://localhost:4200.

3. Stabilire un valore di riferimento

Il tuo punto di partenza è un gioco Angular Cipher, ma non funziona ancora. Angular Signals supporterà la funzionalità del gioco.

Gioco di crittografia angolare nello stile di una console da gioco verde vintage, con un messaggio nascosto sullo schermo "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

Per iniziare, esamina la versione finale di ciò che stai creando: Angular Signals Cypher.

  1. Visualizza il messaggio codificato sullo schermo.
  2. Trascina un pulsante con una lettera nel tastierino per cercare di risolvere il codice e decodificare il messaggio segreto.
  3. In caso di esito positivo, osserva come il messaggio viene aggiornato per decodificare una parte maggiore del messaggio segreto.
  4. Fai clic su Personalizza per modificare il mittente e il messaggio, quindi fai clic su Crea e copia URL per visualizzare i valori sullo schermo e la modifica dell'URL.
  5. 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.

GIF del gioco Angular Cypher, con un messaggio nascosto che viene decodificato sullo schermo per scrivere "Gli indicatori angolari sono oggi disponibili nell'anteprima per gli sviluppatori nella versione 16!".

4. Definisci il 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 a partire dai valori di altri indicatori. Insieme, i segnali creano un grafo diretto di dipendenze che modella il flusso dei dati nella tua app.

Angular può utilizzare le notifiche degli indicatori per sapere quali componenti devono essere rilevati dalle modifiche 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 giocatore. 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, esegui i seguenti passaggi sotto il commento TODO(1): Define your first signal() in ogni file:

  1. Nel file service.message.ts, utilizza la raccolta degli indicatori per rendere reattivo superSecretMessage:

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, probabilmente riscontrerai errori nei punti in cui in precedenza facevi 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 tu legga il valore, chiama il getter dell'indicatore superSecretMessage(). Ogni volta che scrivi il valore, utilizza l'API .set su SettableSignal per impostare il nuovo valore per il messaggio.

  1. Nei file secret-message.ts e service.message.ts, aggiorna tutti i riferimenti di superSecretMessage in superSecretMessage():

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()

Esplora gli altri due indicatori

  • Tieni presente che nella tua app sono presenti altri due indicatori:

src/app/cipher/service.cipher.ts

cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);

CipherService definisce un segnale cipher, una mappatura generata in modo casuale di coppie chiave-valore di una lettera dell'alfabeto a una nuova lettera cipher. Lo utilizzi per criptare il messaggio e determinare se il giocatore trova una corrispondenza sulla tastiera.

Hai anche un indicatore decodedCipher delle coppie chiave-valore decodificate correttamente che aggiungerai man mano che il giocatore risolve il codice.

Un attributo unico e potente del design della libreria Signals di Angular è che puoi introdurre la reattività ovunque. Dopo aver definito gli indicatori una volta nei servizi dell'app, puoi utilizzarli in un modello, in componenti, in pipe, in altri servizi o ovunque tu possa scrivere codice dell'applicazione. Non sono limitati o vincolati all'ambito di un componente.

Verificare le modifiche

  • Devi completare un altro passaggio prima che l'app funzioni. Per il momento, prova ad aggiungere un console.log() in parti diverse dell'app per vedere come viene impostato il nuovo superSecretMessage.

Stackblitz con un messaggio console.log() che mostra il messaggio superSecretMessage che registra correttamente il nuovo messaggio.

5. Definisci la tua prima funzione computed()

In molte situazioni potresti ricavare uno stato da valori esistenti. È meglio che lo stato derivato venga aggiornato quando cambia il valore dipendente.

Con computed(), puoi esprimere in modo dichiarativo un indicatore che ricava il proprio 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, solvedMessage non viene aggiornato quando modifichi secretMessage, decodedCipher o superSecretMessage. Di conseguenza, non visualizzi aggiornamenti sullo schermo quando il giocatore risolve il codice.

Se imposti solvedMessage come calcolato, crei un contesto reattivo in modo che, quando aggiorni il messaggio o risolvi la crittografia, tu possa dedurre l'aggiornamento dello stato dalle dipendenze monitorate.

Per convertire solvedMessage in computed(), esegui i seguenti passaggi sotto il commento TODO(2): Define your first computed() in ogni file:

  1. Nel file service.message.ts, utilizza la libreria Signals per rendere solvedMessage reattivo:

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, probabilmente riscontrerai errori nei punti in cui in precedenza facevi riferimento a solvedMessage. Questo perché hai modificato il tipo di superSecretMessage da string a Signal<string>, una funzione. Per risolvere il problema, puoi sostituire tutti i riferimenti a solvedMessage con solvedMessage().

  1. Nel file secret-message.ts, aggiorna tutti i riferimenti di solvedMessage in solvedMessage():

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, quindi non puoi modificarne direttamente il valore. Il suo valore viene mantenuto aggiornato ogni volta che viene aggiornato uno dei suoi indicatori di dipendenza (secretMessage e decodedCipher).

Esplora le altre due computed() funzioni

  • 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.

CipherService definisce un unsolvedAlphabet calcolato, un elenco di tutte le lettere che il giocatore non ha risolto, che deriva dall'elenco delle chiavi di crittografia risolte in decodedCipher.

Verificare le modifiche

Ora che superSecretMessage è un indicatore e solvedMessage è un valore calcolato, l'app dovrebbe funzionare. Prova le funzionalità del gioco:

  1. Trascina un LetterGuessComponent in un LetterKeyComponent di CipherComponent per risolvere la crittografia e decodificare il messaggio segreto.
  2. Guarda come si aggiorna SecretMessageComponent man mano che decodifichi altro del messaggio segreto.
  3. Fai clic su Personalizza per modificare il mittente e il messaggio, quindi fai clic su Crea e copia URL per visualizzare i valori sullo schermo e la modifica dell'URL.
  4. 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.

GIF del gioco Angular Cypher, con un messaggio nascosto decodificato sullo schermo che indica &quot;Angular Signals è in anteprima per sviluppatori nella versione 16 oggi!&quot;

6. Aggiungi il tuo primo effetto()

A volte potresti voler che si verifichi qualcosa quando un indicatore ha un nuovo valore. Con effect(), puoi pianificare ed eseguire una funzione di gestore in risposta alla modifica 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():

  1. Nel file cipher.ts, pianifica 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.

Verificare le modifiche

  • Prova a decifrare il codice (suggerimento: puoi cambiare il messaggio con un messaggio breve per eseguire il test più velocemente). Uno scoppiettante coriandoli si congratula con te per il tuo primo effect()!

GIF del gioco Angular Cypher, con un messaggio nascosto che viene decodificato sullo schermo per scrivere &quot;È tempo di coriandoli!&quot; e spara coriandoli che si accendono quando il messaggio è risolto.

7. Complimenti!

Il tuo codice Angular è 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. 🎉

Il gioco Angular Cypher è stato risolto con un messaggio nascosto sullo schermo con &quot;Gli indicatori Angular sono oggi disponibili nell&#39;anteprima per gli sviluppatori nella v16!&quot;.

Ora nella cassetta degli attrezzi di Angular sono disponibili 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: