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

Tín hiệu Angular giới thiệu 3 dữ liệu nguyên gốc phản ứng mà bạn biết và yêu thích, đơn giản hoá quá trình phát triển và giúp bạn tạo ứng dụng nhanh hơn theo mặc định.

Sản phẩm bạn sẽ tạo ra

  • Bạn sẽ tìm hiểu về 3 dữ liệu gốc phản ứng được giới thiệu với Tín hiệu góc: signal(), computed()effect().
  • Sử dụng Angular Signals để hỗ trợ trò chơi Angular Cipher. Thuật toán mật mã là các 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ã một tin nhắn bí mật bằng cách kéo và thả các manh mối để giải một thuật toán mật mã, tùy chỉnh tin nhắn và chia sẻ URL để gửi tin nhắn bí mật cho bạn bè.

Trò chơi Angular Cypher theo phong cách máy chơi trò chơi màu xanh lục cổ điển, với thông điệp ẩ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. Stackblitz là phương thức được đề xuất để thực hiện lớp học lập trình này. Thay vào đó, hãy sao chép 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 Stackblitz trong trình duyệt web bạn yêu thích:

  1. Mở một thẻ trình duyệt mới rồi truy cập 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 thay thế để thực hiện 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 ưa thích.
  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 dùng lệnh ng serve.
  7. Mở một thẻ trình duyệt truy cập vào 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 được. 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 máy chơi trò chơi màu xanh lục cổ điển, với thông điệp ẩ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 gì bạn sẽ xây dựng: Angular Signals Cypher.

  1. Xem thông báo được 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ã mật mã và giải mã tin nhắn bí mật.
  3. Khi thành công, hãy xem cách tin nhắn cập nhật để giải mã thêm nhiều tin nhắn 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à URL thay đổi.
  5. Bật mí thêm cho bạn: Sao chép và dán URL vào thẻ mới hoặc chia sẻ với bạn bè rồi 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 "Angular Signals đang ở bản dùng thử cho nhà phát triển 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 khi nào giá trị này thay đổi. Một số tín hiệu có thể được thay đổi trực tiếp, trong khi một số khác thì tính 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 đồ định hướng về các phần phụ thuộc, giúp lập mô hình luồng dữ liệu trong ứng dụng của bạn.

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 điệp 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 Tùy chỉnh bị lỗi. Bạn có thể giải quyết vấn đề này bằng một tín hiệu.

Khi đặ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 mà phụ thuộc vào khả năng 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 phần ghi chú TODO(1): Define your first signal() của mỗi tệp:

  1. Trong tệp service.message.ts, hãy sử dụng thư viện Tín hiệu để khiến 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ả tệp 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(). Bất cứ khi 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 các tệp secret-message.tsservice.message.ts, hãy cập nhật mọi 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, là sự liên kết các cặp khoá-giá trị gồm một chữ cái trong bảng chữ cái được tạo ngẫu nhiên đế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ả phù hợ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ị đã được giải mã thành công mà bạn sẽ thêm vào khi người chơi giải 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 tín hiệu một lần trong các dịch vụ của ứng dụng. Bạn có thể sử dụng các tín hiệu đó trong một mẫu, thành phần, đường ống, các dịch vụ khác hay bất cứ nơi nào bạn có thể viết mã xử lý ứng dụng. Chúng không bị giới hạn hay ràng buộc với một phạm vi thành phần.

Xác minh các thay đổi

  • Bạn còn một bước nữa cần thực hiện trước khi ứng dụng hoạt động. Bây giờ, hãy thử thêm console.log() vào các phần khác nhau của ứng dụng để xem superSecretMessage mới đang được thiết lập như thế nào.

Stackblitz có thông báo console.log() cho thấy SuperSecretMessage đang ghi nhật ký chính xác tin nhắn mới.

5. Xác định Compute() đầu tiên

Trong nhiều trường hợp, bạn có thể tự lấy trạng thái từ các giá trị hiện có. Tốt hơn là 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ể khai báo tín hiệu nhận được giá trị từ các tín hiệu khác.

Chuyển đổi solvedMessage thành computed()

solvedMessage chuyển đổi giá trị secretMessage từ trạng thái đã mã hoá sang trạng thái được giải mã bằng tín hiệu decodedCipher.

Điều này cực kỳ thú vị vì bạn có thể thấy mình đang lấy một giá trị tính toán dựa trên một giá trị khác đã tính toán. Vì vậy, bất cứ khi nào một tín hiệu trong ngữ cảnh phản ứng được ánh xạ đó 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ật 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 hàm superSecretMessage từ string thành Signal<string>. Bạn có thể khắc phục vấn đề này bằng cách thay đổi mọi tệp 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 thuộc tính này. Thay vào đó, giá trị của biến này sẽ được cập nhật mỗi khi một trong các tín hiệu phần phụ thuộc (secretMessagedecodedCipher) được cập nhật.

Khám phá hai hàm computed() khác

  • Hãy lưu ý rằng bạn có hai giá trị được tính 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 đã tính là một danh sách gồm tất 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ã đã được giải trong decodedCipher.

Xác minh các thay đổi

Hiện tại, superSecretMessage là một tín hiệu và solvedMessage đã được tính toán nên ứng dụng này 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à URL thay đổi.
  4. Bật mí thêm cho bạn: Sao chép và dán URL vào thẻ mới hoặc chia sẻ với bạn bè rồi 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 hiệu ứng đầu tiên()

Đôi khi, bạn có thể muốn điều gì đó xảy ra khi một 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 hoa giấy khi mật mã được giải

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 nhận xét TODO(3): Add your first effect():

  1. Trong tệp cipher.ts, hãy lên lịch để thêm hoa 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 ý cách hiệu ứng này phụ thuộc vào một tín hiệu và giá trị đã 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 tràng pháo hoa giấy sẽ chúc mừng bạn trong effect() đầu tiên!

Ả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 để đọc dòng chữ &quot;Confetti time!&quot; và pháo hoa giấy sẽ vang lên khi tin nhắn được giải quyết.

7. Xin chúc mừng!

Thuật toán mật 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ẻ cho mạng xã hội của chúng ta tại @Angular để chúng tôi có thể giải mã! 🎉

Trò chơi Angular Cypher được giải quyết bằng một thông điệp ẩn trên màn hình &quot;Angular Signals is in v16 today!&quot; (Tín hiệu Angular đang ở bản dùng thử cho nhà phát triển trong phiên bản 16!)

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 này: