1. Прежде чем начать
Angular Signals представляет три реактивных примитива для Angular, которые вы знаете и любите, упрощая вашу разработку и помогая создавать более быстрые приложения по умолчанию.
Что ты построишь
- Вы узнаете о трех реактивных примитивах, представленных в Angular Signals:
signal()
,computed()
иeffect()
. - Используйте сигналы Angular для запуска игры Angular Cipher. Шифры — это системы шифрования и дешифрования данных. В этой игре пользователи могут расшифровать секретное сообщение, перетаскивая подсказки, чтобы разгадать шифр, настроить сообщение и поделиться URL-адресом для отправки секретных сообщений друзьям.
Предварительные условия
- Знание Angular и Typescript
- Рекомендуется: посмотрите «Переосмысление реактивности с помощью сигналов» , чтобы узнать о библиотеке Angular Signals.
2. Получите код
Все, что вам нужно для этого проекта, находится в Stackblitz. Stackblitz — рекомендуемый метод для работы с этой лабораторией кода. В качестве альтернативы клонируйте код и откройте его в своей любимой среде разработки.
Откройте Stackblitz и запустите приложение.
Чтобы начать, откройте ссылку Stackblitz в своем любимом веб-браузере:
- Откройте новую вкладку браузера и перейдите по адресу https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service. массаж.ц
- Форк Stackblitz, чтобы создать собственное редактируемое рабочее пространство. Stackblitz должен автоматически запустить приложение, и все готово!
Альтернатива: клонировать репозиторий и использовать приложение.
Использование VSCode или локальной IDE — альтернативный метод работы с этой лабораторией кода:
- Откройте новую вкладку браузера и перейдите по адресу https://github.com/angular/codelabs/tree/signals-get-started .
- Создайте форк и клонируйте репозиторий и используйте команду
cd codelabs/
для перемещения в репозиторий. - Проверьте ветку стартового кода с помощью команды
git checkout signals-get-started
. - Откройте код в VSCode или предпочитаемой вами IDE.
- Чтобы установить зависимости, необходимые для запуска сервера, используйте команду
npm install
. - Чтобы запустить сервер, используйте команду
ng serve
. - Откройте вкладку браузера по адресу http://localhost:4200 .
3. Установите базовый уровень
Ваша отправная точка — игра Angular Cipher, но она пока не работает. Angular Signals обеспечит функциональность игры.
Для начала ознакомьтесь с готовой версией того, что вы будете создавать: Angular Signals Cypher .
- Просмотрите закодированное сообщение на экране.
- Перетащите кнопку с буквой на клавиатуре, чтобы разгадать шифр и расшифровать секретное сообщение.
- В случае успеха посмотрите, как сообщение обновляется, чтобы расшифровать больше секретного сообщения.
- Нажмите «Настроить», чтобы изменить отправителя и сообщение, а затем нажмите «Создать и скопировать URL-адрес» , чтобы увидеть значения на экране и изменение URL-адреса.
- Бонус: скопируйте и вставьте URL-адрес в новую вкладку или поделитесь им с другом и посмотрите, как отправитель и сообщение хранятся в URL-адресе.
4. Определите свой первый сигнал()
Сигнал — это значение, которое может сообщить Angular об изменении. Некоторые сигналы можно изменять напрямую, тогда как другие вычисляют свои значения на основе значений других сигналов. Вместе сигналы создают ориентированный граф зависимостей, который моделирует поток данных в вашем приложении.
Angular может использовать уведомления от сигналов, чтобы узнать, какие компоненты необходимо обнаружить, или выполнить определенные вами функции эффектов .
Преобразовать superSecretMessage
в signal()
superSecretMessage
— это значение в MessageService
, которое определяет секретное сообщение, которое декодирует игрок. В настоящее время значение не уведомляет приложение об изменениях, поэтому кнопка «Настроить» не работает. Решить это можно с помощью сигнала.
Сделав superSecretMessage
сигналом, вы можете уведомить части приложения, которые зависят от того, когда сообщение изменилось. Когда вы настраиваете сообщение в диалоговом окне, вы устанавливаете сигнал для обновления остальной части приложения новым сообщением.
Чтобы определить свой первый сигнал, выполните следующие шаги в разделе TODO(1): Define your first signal()
в каждом файле:
- В файле
service.message.ts
используйте библиотеку Signals, чтобы сделатьsuperSecretMessage
реактивным:
src/app/secret-message/service.message.ts
superSecretMessage = signal(
'Angular Signals are in developer preview in v16 today!'
);
Это автоматически предложит вам импортировать signal
из @angular/core
. Если вы обновите страницу, вы, скорее всего, столкнетесь с ошибками там, где вы ранее ссылались на superSecretMessage
. Это связано с тем, что вы изменили тип superSecretMessage
со string
на SettableSignal<string>
. Вы можете исправить это, изменив все ссылки superSecretMessage
на использование Signals API. Где бы вы ни прочитали значение, вызовите метод получения сигнала superSecretMessage()
. И где бы вы ни записывали значение, используйте API .set
в SettableSignal
чтобы установить новое значение для сообщения.
- В файлах
secret-message.ts
иservice.message.ts
обновите все ссылкиsuperSecretMessage
на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()
Изучите два других сигнала
- Обратите внимание, что в вашем приложении есть еще два сигнала:
src/app/cipher/service.cipher.ts
cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);
CipherService
определяет сигнал cipher
— случайно сгенерированное сопоставление пар ключ-значение одной буквы алфавита с новой буквой cipher
. Вы используете это, чтобы зашифровать сообщение и определить, находит ли игрок успешное совпадение на клавиатуре.
У вас также есть сигнал decodedCipher
об успешно декодированных парах ключ-значение, который вы будете добавлять по мере того, как игрок разгадывает шифр.
Уникальным и мощным свойством дизайна библиотеки Signals Angular является то, что вы можете внедрить реактивность повсюду. Вы определили сигналы один раз в службах приложения и можете использовать их в шаблоне, компонентах, каналах, других службах или везде, где можно писать код приложения. Они не ограничены и не привязаны к области действия компонента.
Проверьте изменения
- Вам нужно выполнить еще один шаг, прежде чем приложение заработает. А пока попробуйте добавить
console.log()
в разные части вашего приложения, чтобы увидеть, как устанавливается ваше новоеsuperSecretMessage
.
5. Определите свой первый вычисляемый()
Во многих ситуациях вы можете обнаружить, что получаете состояние из существующих значений. Лучше обновлять производное состояние при изменении зависимого значения.
С помощью computed()
вы можете декларативно выразить сигнал, который получает свое значение из других сигналов.
Преобразовать solvedMessage
в computed()
solvedMessage
преобразует значение secretMessage
из закодированного в декодированное с помощью сигнала decodedCipher
.
Это очень здорово, потому что вы можете видеть, что вы получаете вычисленное значение на основе другого вычисленного, поэтому каждый раз, когда сигнал в этом сопоставленном реактивном контексте изменяется, зависимости уведомляются.
В настоящее solvedMessage
не обновляется при изменении secretMessage
, decodedCipher
или superSecretMessage
. Таким образом, вы не видите обновлений на экране, когда игрок разгадывает шифр.
solvedMessage
вычисляемым, вы создаете реактивный контекст, чтобы при обновлении сообщения или раскрытии шифра вы могли получить обновление состояния из отслеживаемых зависимостей.
Чтобы преобразовать solvedMessage
в computed()
, выполните следующие шаги в TODO(2): Define your first computed()
в каждом файле:
- В файле
service.message.ts
используйте библиотеку Signals, чтобыsolvedMessage
реактивным:
src/app/secret-message/service.message.ts
solvedMessage = computed(() =>
this.translateMessage(
this.secretMessage(),
this.cipher.decodedCipher()
)
);
Это автоматически предложит вам импортировать computed
из @angular/core
. Если вы обновите страницу, вы, скорее всего, столкнетесь с ошибками там, где вы ранее ссылались solvedMessage
. Это связано с тем, что вы изменили тип superSecretMessage
со string
на функцию Signal<string>
. Вы можете исправить это, изменив все solvedMessage
solvedMessage()
.
- В файле
secret-message.ts
обновите всеsolvedMessage
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>
Обратите внимание: в отличие от superSecretMessage
, solvedMessage
не является SettableSignal
— вы не можете изменить его значение напрямую. Вместо этого его значение обновляется всякий раз, когда обновляется любой из его сигналов зависимости ( secretMessage
и decodedCipher
).
Изучите две другие функции computed()
- Обратите внимание, что в вашем приложении есть еще два вычисляемых значения:
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)
)
);
MessageService
определяет вычисленное secretMessage
, superSecretMessage
, закодированное cipher
, над разгадкой которого работают игроки.
CipherService
определяет вычисленный unsolvedAlphabet
— список всех букв, которые игрок не разгадал, который получается из списка решенных ключей шифрования в decodedCipher
.
Проверьте изменения
Теперь, когда superSecretMessage
является сигналом, solvedMessage
— вычисляемым, приложение должно работать! Оцените возможности игры:
- Перетащите компонент
LetterGuessComponent
вLetterKeyComponent
вCipherComponent
, чтобы работать над решением шифра и декодированием секретного сообщения. - Посмотрите, как обновляется
SecretMessageComponent
по мере того, как вы декодируете больше секретного сообщения. - Нажмите «Настроить», чтобы изменить отправителя и сообщение, а затем нажмите «Создать и скопировать URL-адрес» , чтобы увидеть значения на экране и изменение URL-адреса.
- Бонус: скопируйте и вставьте URL-адрес в новую вкладку или поделитесь им с другом и посмотрите, как отправитель и сообщение хранятся в URL-адресе.
6. Добавьте свой первый эффект()
Бывают случаи, когда вам может потребоваться, чтобы что-то произошло, когда сигнал имеет новое значение. С помощью effect()
вы можете запланировать и запустить функцию-обработчик в ответ на изменение сигналов.
Добавьте конфетти, когда шифр будет раскрыт.
Теперь, когда приложение работает, вы можете добавить немного веселья, добавив конфетти, когда шифр разгадан и секретное сообщение расшифровано.
Чтобы добавить конфетти, выполните следующие шаги в TODO(3): Add your first effect()
:
- В файле
cipher.ts
запланируйте эффект добавления конфетти при декодировании сообщения:
src/приложение/шифр/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 });
}
});
}
Обратите внимание, как этот эффект зависит от сигнала и вычисленного значения: this.messages.superSecretMessage()
и this.messages.solvedMessage()
.
Эффект помогает запланировать функцию конфетти внутри реактивного контекста для отслеживания и повторной оценки при обновлении ее зависимостей.
Проверьте изменения
- Попробуйте разгадать шифр (подсказка: вы можете изменить сообщение на что-нибудь короткое, чтобы проверить быстрее!). Конфетти поздравит вас с первым
effect()
!
7. Поздравляем!
Ваш Angular Cipher теперь готов декодировать и делиться секретными сообщениями! У вас есть сообщение для команды Angular? Отметьте наши социальные сети @Angular, чтобы мы могли их расшифровать! 🎉
Теперь в вашем наборе инструментов Angular есть три новых реактивных примитива, которые по умолчанию упрощают разработку и создают более быстрые приложения.
Узнать больше
Ознакомьтесь с этими лабораториями кода:
Прочтите эти материалы:
- Angular.io
- Переосмысление реактивности с помощью сигналов (Google I/O 2023)
- Что нового в Angular (Google I/O 2023)