Bắt đầu sử dụng Tín hiệu góc

1. Trước khi bắt đầu

biểu trưng Angular màu đen

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

Trò chơi Angular Cypher theo phong cách của một bảng điều khiển trò chơi màu xanh lục cổ điển, với thông báo ẩn trên màn hình "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

Điều kiện tiên quyết

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:

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

  1. 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.
  2. 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ữ.
  3. Hãy xem nhánh mã khởi đầu bằng lệnh git checkout signals-get-started.
  4. Mở mã trong VSCode hoặc IDE mà bạn muốn dùng.
  5. Để 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.
  6. Để chạy máy chủ, hãy sử dụng lệnh ng serve.
  7. 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.

Trò chơi Angular Cypher theo phong cách của một bảng điều khiển trò chơi màu xanh lục cổ điển, với thông báo ẩn trên màn hình "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

Để 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.

  1. Xem thông báo đã mã hoá trên màn hình.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

Ảnh GIF của trò chơi Angular Cypher, trong đó thông báo ẩn được giải mã trên màn hình để đánh vần "Angular Signals are in developer preview in v16 today!" (Tín hiệu Angular đang ở bản xem trước dành cho nhà phát triển trong phiên bản 16 hôm nay!)

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:

  1. Trong tệp service.message.ts, hãy sử dụng thư viện Signals để tạo superSecretMessage 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.

  1. Trong tệp secret-message.tsservice.message.ts, hãy cập nhật tất cả các tệp tham chiếu của superSecretMessage thành 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()

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ập superSecretMessage mới.

Stackblitz với thông báo console.log() cho thấy superSecretMessage ghi lại chính xác thông báo 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:

  1. Trong tệp service.message.ts, hãy sử dụng thư viện Tín hiệu để khiến solvedMessage 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().

  1. Trong tệp secret-message.ts, hãy cập nhật mọi tệp tham chiếu của solvedMessage thành 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>

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 (secretMessagedecodedCipher) đượ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:

  1. Kéo và thả một LetterGuessComponent vào LetterKeyComponent trong CipherComponent của bạn để giải mã mật mã và giải mã thư bí mật.
  2. Hãy xem cách SecretMessageComponent cập nhật khi bạn giải mã thêm nhiều thư bí mật.
  3. 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.
  4. 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.

Ảnh GIF về trò chơi Angular Cypher, với một thông điệp ẩn được giải mã trên màn hình để đánh vần &quot;Angular Signals đang ở bản dùng thử cho nhà phát triển phiên bản 16 hôm nay!&quot;

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

  1. 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()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!

Ảnh GIF của trò chơi Angular Cypher, trong đó một thông báo ẩn được giải mã trên màn hình để đánh vần &quot;Thời gian tung hoa giấy!&quot; và hoa giấy sẽ bung ra khi thông báo được giải mã.

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ã! 🎉

Giải quyết trò chơi Angular Cypher bằng thông báo ẩn trên màn hình &quot;Angular Signals are in developer preview in v16 today!&quot; (Tín hiệu Angular đang ở bản xem trước dành cho nhà phát triển trong phiên bản 16 hôm nay!)

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: