1. Trước khi bắt đầu
Angular Signals giới thiệu ba nguyên hàm phản ứng cho Angular mà bạn biết và yêu thích, giúp đơn giản hoá quá trình phát triển và giúp bạn xây dựng ứng dụng nhanh hơn theo mặc định.
Sản phẩm bạn sẽ tạo ra
- Bạn tìm hiểu về ba nguyên hàm phản ứng được giới thiệu với Tín hiệu Angular:
signal()
,computed()
vàeffect()
. - Sử dụng Tín hiệu Angular để hỗ trợ trò chơi Angular Cipher. Thuật toán mật mã là hệ thống để mã hoá và giải mã dữ liệu. Trong trò chơi này, người dùng có thể giải mã thông điệp bí mật bằng cách kéo và thả các manh mối để giải mã, tuỳ chỉnh thông điệp và chia sẻ URL để gửi thông điệp bí mật cho bạn bè.
Điều kiện tiên quyết
- Có kiến thức về Angular và Typescript
- Đề xuất: Xem video Suy nghĩ lại về phản ứng bằng tín hiệu để tìm hiểu về thư viện Tín hiệu Angular
2. Lấy mã
Mọi thứ bạn cần cho dự án này đều có trong Stackblitz. Bạn nên sử dụng Stackblitz để tham gia lớp học lập trình này. Ngoài ra, bạn có thể nhân bản mã và mở mã đó trong môi trường phát triển mà bạn yêu thích.
Mở Stackblitz và chạy ứng dụng
Để bắt đầu, hãy mở đường liên kết đến Stackblitz trong trình duyệt web mà bạn yêu thích:
- Mở một thẻ trình duyệt mới rồi truy cập vào https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service.massage.ts
- Phát triển nhánh Stackblitz để tạo không gian làm việc có thể chỉnh sửa của riêng bạn. Stackblitz sẽ tự động chạy ứng dụng và bạn đã sẵn sàng!
Phương án thay thế: Sao chép kho lưu trữ và phân phát ứng dụng
Sử dụng VSCode hoặc IDE cục bộ là một phương thức khác để xử lý lớp học lập trình này:
- Mở một thẻ trình duyệt mới rồi truy cập vào https://github.com/angular/codelabs/tree/signals-get-started.
- Phát triển nhánh và sao chép kho lưu trữ, đồng thời dùng lệnh
cd codelabs/
để di chuyển vào kho lưu trữ. - Hãy xem nhánh mã khởi đầu bằng lệnh
git checkout signals-get-started
. - Mở mã trong VSCode hoặc IDE mà bạn muốn dùng.
- Để cài đặt các phần phụ thuộc cần thiết để chạy máy chủ, hãy dùng lệnh
npm install
. - Để chạy máy chủ, hãy sử dụng lệnh
ng serve
. - Mở một thẻ trình duyệt đến http://localhost:4200.
3. Thiết lập đường cơ sở
Điểm xuất phát của bạn là một trò chơi Angular Cipher, nhưng trò chơi này chưa hoạt động. Tín hiệu Angular sẽ hỗ trợ chức năng của trò chơi.
Để bắt đầu, hãy xem qua phiên bản hoàn chỉnh của những nội dung bạn sẽ xây dựng: Angular Signals Cypher.
- Xem thông báo đã mã hoá trên màn hình.
- Kéo và thả nút chữ cái trong bàn phím để giải mã và giải mã thông điệp bí mật.
- Khi thành công, hãy xem cách thông báo cập nhật để giải mã thêm thông báo bí mật.
- Nhấp vào Tuỳ chỉnh để thay đổi Người gửi và Thông báo, sau đó nhấp vào Tạo và sao chép URL để xem các giá trị trên màn hình và thay đổi URL.
- Phần thưởng: Sao chép và dán URL vào một thẻ mới hoặc chia sẻ với bạn bè để xem cách người gửi và tin nhắn được lưu trữ trong URL.
4. Xác định tín hiệu đầu tiên()
Tín hiệu là một giá trị có thể cho Angular biết thời điểm thay đổi. Một số tín hiệu có thể được thay đổi trực tiếp, trong khi một số tín hiệu khác tính toán giá trị của chúng từ giá trị của các tín hiệu khác. Các tín hiệu cùng nhau tạo ra một biểu đồ có hướng của các phần phụ thuộc mô hình hoá cách dữ liệu di chuyển trong ứng dụng.
Angular có thể sử dụng thông báo từ các tín hiệu để biết thành phần nào cần được phát hiện thay đổi hoặc để thực thi các hàm hiệu ứng mà bạn xác định.
Chuyển đổi superSecretMessage
thành signal()
superSecretMessage
là một giá trị trong MessageService
xác định thông báo bí mật mà người chơi giải mã. Hiện tại, giá trị này không thông báo cho ứng dụng về các thay đổi, vì vậy, nút Customize (Tuỳ chỉnh) bị hỏng. Bạn có thể giải quyết vấn đề này bằng một tín hiệu.
Bằng cách đặt superSecretMessage
làm tín hiệu, bạn có thể thông báo cho các phần của ứng dụng phụ thuộc vào việc biết thời điểm thông báo thay đổi. Khi tuỳ chỉnh thông báo trong hộp thoại, bạn sẽ thiết lập tín hiệu để cập nhật phần còn lại của ứng dụng bằng thông báo mới.
Để xác định tín hiệu đầu tiên, hãy thực hiện các bước sau trong nhận xét TODO(1): Define your first signal()
trong mỗi tệp:
- Trong tệp
service.message.ts
, hãy sử dụng thư viện Signals để tạosuperSecretMessage
phản ứng:
src/app/secret-message/service.message.ts
superSecretMessage = signal(
'Angular Signals are in developer preview in v16 today!'
);
Thao tác này sẽ tự động nhắc bạn nhập signal
từ @angular/core
. Nếu làm mới trang, có thể bạn sẽ gặp lỗi mà trước đó bạn đã tham chiếu đến superSecretMessage
. Điều này là do bạn đã thay đổi loại superSecretMessage
từ string
thành SettableSignal<string>
. Bạn có thể khắc phục vấn đề này bằng cách thay đổi tất cả tham chiếu của superSecretMessage
để sử dụng API Tín hiệu. Bất cứ khi nào bạn đọc giá trị, hãy gọi phương thức getter Tín hiệu superSecretMessage()
. Và bất cứ nơi nào bạn viết giá trị, hãy sử dụng API .set
trên SettableSignal
để đặt giá trị mới cho thông báo.
- Trong tệp
secret-message.ts
vàservice.message.ts
, hãy cập nhật tất cả các tệp tham chiếu củasuperSecretMessage
thànhsuperSecretMessage()
:
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()
Khám phá hai tín hiệu khác
- Lưu ý rằng bạn có hai tín hiệu khác trong ứng dụng:
src/app/cipher/service.cipher.ts
cipher = signal(this.createNewCipherKey());
decodedCipher = signal<CipherKey[]>([]);
CipherService
xác định tín hiệu cipher
, một ánh xạ được tạo ngẫu nhiên của các cặp khoá-giá trị của một chữ cái trong bảng chữ cái đến một chữ cái cipher
mới. Bạn sử dụng hàm này để xáo trộn thông báo và xác định xem người chơi có tìm thấy kết quả khớp trên bàn phím hay không.
Bạn cũng có tín hiệu decodedCipher
của các cặp khoá-giá trị đã giải mã thành công mà bạn sẽ thêm vào khi người chơi giải mã được mật mã.
Một thuộc tính độc đáo và mạnh mẽ trong thiết kế thư viện Tín hiệu của Angular là bạn có thể giới thiệu tính năng phản ứng ở mọi nơi. Bạn đã xác định các tín hiệu một lần trong các dịch vụ của ứng dụng và bạn có thể sử dụng các tín hiệu đó trong mẫu, thành phần, ống, các dịch vụ khác hoặc bất cứ nơi nào bạn có thể viết mã ứng dụng. Các thành phần này không bị giới hạn hoặc ràng buộc với phạm vi thành phần.
Xác minh thay đổi
- Bạn cần thực hiện thêm một bước nữa thì ứng dụng mới hoạt động. Hiện tại, hãy thử thêm
console.log()
vào các phần khác nhau của ứng dụng để xem cách thiết lậpsuperSecretMessage
mới.
5. Xác định computed() đầu tiên
Trong nhiều trường hợp, bạn có thể thấy mình bắt nguồn trạng thái từ các giá trị hiện có. Bạn nên cập nhật trạng thái phái sinh khi giá trị phụ thuộc thay đổi.
Với computed()
, bạn có thể biểu thị một tín hiệu lấy giá trị từ các tín hiệu khác theo cách khai báo.
Chuyển đổi solvedMessage
thành computed()
solvedMessage
dịch giá trị secretMessage
từ đã mã hoá sang đã giải mã bằng tín hiệu decodedCipher
.
Điều này thật tuyệt vời vì bạn có thể thấy mình đang lấy dữ liệu đã tính toán dựa trên một dữ liệu đã tính toán khác, vì vậy, bất cứ khi nào một tín hiệu trong ngữ cảnh phản ứng được liên kết đó thay đổi, các phần phụ thuộc sẽ được thông báo.
Hiện tại, solvedMessage
không được cập nhật khi bạn thay đổi secretMessage
, decodedCipher
hoặc superSecretMessage
. Vì vậy, bạn sẽ không thấy nội dung cập nhật trên màn hình khi người chơi giải mã.
Bằng cách biến solvedMessage
thành một tính toán, bạn sẽ tạo một ngữ cảnh phản ứng để khi cập nhật thông báo hoặc giải thuật toán mật mã, bạn có thể lấy được thông tin cập nhật trạng thái từ các phần phụ thuộc được theo dõi.
Để chuyển đổi solvedMessage
thành computed()
, hãy thực hiện các bước sau trong nhận xét TODO(2): Define your first computed()
của từng tệp:
- Trong tệp
service.message.ts
, hãy sử dụng thư viện Tín hiệu để khiếnsolvedMessage
phản ứng:
src/app/secret-message/service.message.ts
solvedMessage = computed(() =>
this.translateMessage(
this.secretMessage(),
this.cipher.decodedCipher()
)
);
Thao tác này sẽ tự động nhắc bạn nhập computed
từ @angular/core
. Nếu làm mới trang, có thể bạn sẽ gặp lỗi mà trước đó bạn đã tham chiếu đến solvedMessage
. Điều này là do bạn đã thay đổi loại superSecretMessage
từ string
thành Signal<string>
, một hàm. Bạn có thể khắc phục bằng cách thay đổi tất cả tham chiếu của solvedMessage
thành solvedMessage()
.
- Trong tệp
secret-message.ts
, hãy cập nhật mọi tệp tham chiếu củasolvedMessage
thànhsolvedMessage()
:
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>
Xin lưu ý rằng không giống như superSecretMessage
, solvedMessage
không phải là SettableSignal
– bạn không thể trực tiếp thay đổi giá trị của solvedMessage
. Thay vào đó, giá trị của thuộc tính này được cập nhật bất cứ khi nào một trong hai tín hiệu phần phụ thuộc (secretMessage
và decodedCipher
) được cập nhật.
Khám phá hai hàm computed()
khác
- Lưu ý rằng bạn có hai giá trị được tính toán khác trong ứng dụng:
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
xác định một secretMessage
đã tính toán, superSecretMessage
được mã hoá bởi cipher
mà người chơi giải quyết.
CipherService
xác định một unsolvedAlphabet
được tính toán, danh sách tất cả các chữ cái mà người chơi chưa giải được, được lấy từ danh sách các khoá mật mã đã giải trong decodedCipher
.
Xác minh các thay đổi
Giờ đây, superSecretMessage
là một tín hiệu và solvedMessage
là một giá trị được tính toán, ứng dụng sẽ hoạt động! Kiểm thử các chức năng của trò chơi:
- Kéo và thả một
LetterGuessComponent
vàoLetterKeyComponent
trongCipherComponent
của bạn để giải mã mật mã và giải mã thư bí mật. - Hãy xem cách
SecretMessageComponent
cập nhật khi bạn giải mã thêm nhiều thư bí mật. - Nhấp vào Tuỳ chỉnh để thay đổi Người gửi và Thông báo, sau đó nhấp vào Tạo và sao chép URL để xem các giá trị trên màn hình và thay đổi URL.
- Phần thưởng: Sao chép và dán URL vào một thẻ mới hoặc chia sẻ với bạn bè để xem cách người gửi và tin nhắn được lưu trữ trong URL.
6. Thêm effect() đầu tiên
Đôi khi, bạn có thể muốn một sự kiện xảy ra khi tín hiệu có giá trị mới. Với effect()
, bạn có thể lên lịch và chạy một hàm xử lý để phản hồi các tín hiệu thay đổi.
Thêm pháo hoa khi giải mã được mật mã
Giờ đây, ứng dụng đã hoạt động, bạn có thể thêm chút thú vị bằng cách thêm hoa giấy khi mật mã được giải mã và thông điệp bí mật được giải mã.
Để thêm hoa giấy, hãy thực hiện các bước sau trong chú thích TODO(3): Add your first effect()
:
- Trong tệp
cipher.ts
, hãy lên lịch một hiệu ứng để thêm pháo giấy khi thông báo được giải mã:
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 });
}
});
}
Hãy lưu ý hiệu ứng này phụ thuộc vào tín hiệu và giá trị được tính toán: this.messages.superSecretMessage()
và this.messages.solvedMessage()
.
Hiệu ứng giúp bạn lên lịch cho hàm hoa giấy trong ngữ cảnh phản ứng để theo dõi và đánh giá lại thời điểm cập nhật các phần phụ thuộc.
Xác minh các thay đổi
- Hãy thử giải mật mã (gợi ý: bạn có thể thay đổi thông điệp thành nội dung ngắn gọn để kiểm tra nhanh hơn!). Một màn hình hoa giấy sẽ xuất hiện để chúc mừng bạn về
effect()
đầu tiên!
7. Xin chúc mừng!
Phương thức mã hoá và giải mã Angular của bạn hiện đã sẵn sàng để giải mã và chia sẻ thông điệp bí mật! Bạn có tin nhắn cho nhóm Angular? Hãy gắn thẻ trang mạng xã hội của chúng tôi tại @Angular để chúng tôi có thể giải mã! 🎉
Hiện bạn có 3 dữ liệu gốc phản ứng mới trong hộp công cụ Angular để đơn giản hoá quá trình phát triển và xây dựng ứng dụng nhanh hơn theo mặc định.
Tìm hiểu thêm
Hãy tham khảo các lớp học lập trình sau:
Đọc các tài liệu sau:
- Angular.io
- Tái cân nhắc khả năng phản hồi bằng tín hiệu (Google I/O 2023)
- Tính năng mới trong Angular (Google I/O 2023)