เริ่มต้นใช้งานสัญญาณ Angular

1. ก่อนเริ่มต้น

โลโก้ Angular สีดํา

สัญญาณ Angular จะแนะนำพื้นฐานเชิงรับ 3 ประการใน Angular ที่คุณรู้จักและชื่นชอบ ซึ่งช่วยให้การพัฒนาของคุณง่ายขึ้นและช่วยให้คุณสร้างแอปที่เร็วขึ้นโดยค่าเริ่มต้น

สิ่งที่คุณจะสร้าง

  • คุณจะได้เรียนรู้เกี่ยวกับพรอมิเทีฟแบบเรียลไทม์ 3 รายการที่มาพร้อมกับ Angular Signals ได้แก่ signal(), computed() และ effect()
  • ใช้ Angular Signals เพื่อขับเคลื่อนเกม Angular Cipher การเข้ารหัสเป็นระบบสําหรับเข้ารหัสและถอดรหัสข้อมูล ในเกมนี้ ผู้ใช้สามารถถอดรหัสข้อความลับด้วยการลากและวางคำใบ้เพื่อไขปริศนา ปรับแต่งข้อความ และแชร์ URL เพื่อส่งข้อความลับให้เพื่อน

เกม Angular Cypher ในรูปแบบคอนโซลเกมย้อนยุคสีเขียวพร้อมข้อความที่ซ่อนอยู่บนหน้าจอ "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

ข้อกำหนดเบื้องต้น

  • ความรู้เกี่ยวกับ Angular และ Typescript
  • ขอแนะนํา: ดูวิดีโอ Rethinking Reactivity with Signals เพื่อดูข้อมูลเกี่ยวกับคลัง Signals ของ Angular

2. รับโค้ด

ทุกอย่างที่คุณต้องการสำหรับโปรเจ็กต์นี้อยู่ใน Stackblitz เราขอแนะนําให้ใช้ Stackblitz เพื่อทํา Codelab นี้ หรือจะโคลนโค้ดและเปิดในสภาพแวดล้อมการพัฒนาที่ชื่นชอบก็ได้

เปิด Stackblitz และเรียกใช้แอป

หากต้องการเริ่มต้นใช้งาน ให้เปิดลิงก์ Stackblitz ในเว็บเบราว์เซอร์ที่คุณชื่นชอบ

  1. เปิดแท็บใหม่ในเบราว์เซอร์แล้วไปที่ https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service.massage.ts
  2. แยก Stackblitz เพื่อสร้างพื้นที่ทํางานที่แก้ไขได้ของคุณเอง Stackblitz ควรเรียกใช้แอปโดยอัตโนมัติ และคุณก็พร้อมใช้งาน

ทางเลือก: โคลนที่เก็บและแสดงแอป

การใช้ VSCode หรือ IDE ในเครื่องเป็นอีกวิธีหนึ่งในการทำงานผ่านโค้ดแล็บนี้

  1. เปิดแท็บใหม่ในเบราว์เซอร์แล้วไปที่ https://github.com/angular/codelabs/tree/signals-get-started
  2. แยกและโคลนที่เก็บ แล้วใช้คำสั่ง cd codelabs/ เพื่อย้ายไปยังที่เก็บ
  3. ตรวจสอบสาขาของโค้ดเริ่มต้นด้วยคำสั่ง git checkout signals-get-started
  4. เปิดโค้ดใน VSCode หรือ IDE ที่ต้องการ
  5. หากต้องการติดตั้ง Dependency ที่จําเป็นสําหรับการเรียกใช้เซิร์ฟเวอร์ ให้ใช้คําสั่ง npm install
  6. หากต้องการเรียกใช้เซิร์ฟเวอร์ ให้ใช้คำสั่ง ng serve
  7. เปิดแท็บเบราว์เซอร์ไปที่ http://localhost:4200

3. กำหนดพื้นฐาน

จุดเริ่มต้นคือเกม Angular Cipher แต่ยังไม่ทํางาน Angular Signals จะขับเคลื่อนฟังก์ชันการทำงานของเกม

เกม Angular Cypher ในรูปแบบคอนโซลเกมย้อนยุคสีเขียวพร้อมข้อความที่ซ่อนอยู่บนหน้าจอ "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!"

ในการเริ่มต้นใช้งาน ให้อธิบายถึงสิ่งที่คุณจะสร้างในเวอร์ชันที่เสร็จสมบูรณ์แล้ว ได้แก่ Angular Signals Cypher

  1. ดูข้อความที่เข้ารหัสบนหน้าจอ
  2. ลากและวางปุ่มตัวอักษรโดยใช้ปุ่มกดเพื่อแก้โจทย์และถอดรหัสข้อความลับ
  3. เมื่อดำเนินการเสร็จสิ้นแล้ว ให้ดูว่าข้อความอัปเดตเพื่อถอดรหัสข้อความลับเพิ่มเติมอย่างไร
  4. คลิกปรับแต่งเพื่อเปลี่ยนผู้ส่งและข้อความ แล้วคลิกสร้างและคัดลอก URL เพื่อดูค่าบนหน้าจอและการเปลี่ยนแปลง URL
  5. โบนัส: คัดลอกและวาง URL ในแท็บใหม่ หรือแชร์กับเพื่อน และดูว่าผู้ส่งและข้อความใน URL จัดเก็บอย่างไร

GIF ของเกม Angular Cypher ที่มีข้อความที่ซ่อนอยู่ซึ่งถอดรหัสบนหน้าจอเพื่อสะกดว่า "Angular Signals อยู่ในเวอร์ชันตัวอย่างสำหรับนักพัฒนาซอฟต์แวร์ใน v16 ในวันนี้"

4. กำหนด Signals แรก()

สัญญาณคือค่าที่บอก Angular ได้เมื่อมีการเปลี่ยนแปลง สัญญาณบางรายการเปลี่ยนแปลงได้โดยตรง ขณะที่สัญญาณอื่นๆ จะคํานวณค่าจากค่าของสัญญาณอื่นๆ สัญญาณเหล่านี้จะร่วมกันสร้างกราฟกำกับของความสัมพันธ์ซึ่งจำลองการไหลของข้อมูลในแอป

Angular สามารถใช้การแจ้งเตือนจากสัญญาณเพื่อให้รู้ว่าต้องตรวจหาการเปลี่ยนแปลงคอมโพเนนต์ใดหรือเพื่อเรียกใช้ฟังก์ชัน effect ที่คุณกำหนด

แปลง superSecretMessage เป็น signal()

superSecretMessage คือค่าใน MessageService ที่กําหนดข้อความลับที่ผู้เล่นจะถอดรหัส ซึ่งปัจจุบันค่าดังกล่าวไม่ได้แจ้งให้แอปทราบถึงการเปลี่ยนแปลง ดังนั้นปุ่มปรับแต่งจะใช้งานไม่ได้ คุณแก้ปัญหานี้ได้โดยใช้สัญญาณ

การทำ superSecretMessage เป็นสัญญาณจะช่วยให้คุณแจ้งเตือนส่วนต่างๆ ของแอปที่จำเป็นต้องทราบเมื่อข้อความมีการเปลี่ยนแปลงได้ เมื่อปรับแต่งข้อความในกล่องโต้ตอบ คุณจะตั้งค่าสัญญาณเพื่ออัปเดตส่วนที่เหลือของแอปด้วยข้อความใหม่

หากต้องการกําหนดสัญญาณแรก ให้ทําตามขั้นตอนต่อไปนี้ในส่วนความคิดเห็น TODO(1): Define your first signal() ของแต่ละไฟล์

  1. ในไฟล์ 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 เรียก Signal getter superSecretMessage() ในทุกที่ที่คุณอ่านค่า และไม่ว่าคุณจะเขียนค่าไว้ที่ใดก็ตาม ให้ใช้ .set API ใน SettableSignal เพื่อตั้งค่าใหม่สำหรับข้อความ

  1. ในไฟล์ 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()

สำรวจสัญญาณอีก 2 รายการ

  • โปรดทราบว่าคุณมีสัญญาณอื่นๆ อีก 2 รายการในแอป

src/app/cipher/service.cipher.ts

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

CipherService จะกำหนดสัญญาณ cipher ซึ่งเป็นการจับคู่แบบสุ่มของคู่คีย์-ค่าของตัวอักษร 1 ตัวจากตัวอักษรทั้งหมดกับตัวอักษร cipher ตัวใหม่ คุณใช้ตัวเลือกนี้เพื่อสับเปลี่ยนข้อความและระบุว่าผู้เล่นพบการจับคู่ที่ตรงกันในแป้นพิมพ์หรือไม่

นอกจากนี้ คุณยังมีสัญญาณ decodedCipher ของคู่คีย์-ค่าที่ถอดรหัสสำเร็จซึ่งคุณจะเพิ่มเข้าไปเมื่อผู้เล่นไขรหัสได้

คุณสมบัติเด่นที่เป็นเอกลักษณ์และทรงพลังของการออกแบบคลังสัญญาณของ Angular คือคุณสามารถทำให้เกิดความรู้สึกได้ในทุกที่ คุณได้กำหนดสัญญาณไว้ในบริการของแอปแล้ว และจะใช้สัญญาณดังกล่าวในเทมเพลต คอมโพเนนต์ ไปป์ บริการอื่นๆ หรือที่ใดก็ตามที่คุณสามารถเขียนโค้ดของแอปพลิเคชันได้ ไม่มีการจํากัดหรือผูกกับขอบเขตคอมโพเนนต์

ยืนยันการเปลี่ยนแปลง

  • คุณต้องดำเนินการอีก 1 ขั้นตอนก่อนที่แอปจะใช้งานได้ ในระหว่างนี้ ให้ลองเพิ่ม console.log() ในส่วนต่างๆ ของแอปเพื่อดูว่าระบบตั้งค่า superSecretMessage ใหม่อย่างไร

Stackblitz ที่มีข้อความ console.log() ซึ่งแสดง superSecretMessage ที่บันทึกข้อความใหม่อย่างถูกต้อง

5. กำหนด computed() รายการแรก

ในหลายสถานการณ์ คุณอาจพบว่าตัวเองดึงสถานะมาจากค่าที่มีอยู่ คุณควรอัปเดตสถานะแบบอนุมานเมื่อค่าที่เกี่ยวข้องมีการเปลี่ยนแปลง

computed() ช่วยให้คุณแสดงสัญญาณที่ดึงค่ามาจากสัญญาณอื่นๆ ได้

แปลง solvedMessage เป็น computed()

solvedMessage แปลค่า secretMessage จากที่เข้ารหัสเป็นการถอดรหัสโดยใช้สัญญาณ decodedCipher

ซึ่งเจ๋งกว่าตรงที่คุณเห็นว่าคุณกำลังดึงข้อมูลค่าที่คำนวณแล้วจากค่าที่คำนวณแล้วอีกรายการหนึ่ง ดังนั้นเมื่อใดก็ตามที่สัญญาณภายในบริบทการตอบสนองที่แมปไว้มีการเปลี่ยนแปลง ระบบจะแจ้งให้ทราบถึงข้อมูลที่ต้องพึ่งพา

ปัจจุบัน solvedMessage จะไม่อัปเดตเมื่อคุณเปลี่ยน secretMessage, decodedCipher หรือ superSecretMessage คุณจึงไม่เห็นการอัปเดตบนหน้าจอเมื่อผู้เล่นไขรหัส

การกำหนดให้ solvedMessage เป็นการคำนวณจะเป็นการสร้างบริบทเชิงรับ เพื่อให้เมื่ออัปเดตข้อความหรือแก้โจทย์การเข้ารหัส จะรับการอัปเดตสถานะจากทรัพยากร Dependency ที่ติดตามได้

หากต้องการแปลง solvedMessage เป็น computed() ให้ทําตามขั้นตอนต่อไปนี้ในส่วนความคิดเห็น TODO(2): Define your first computed() ของแต่ละไฟล์

  1. ในไฟล์ 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()

  1. ในไฟล์ 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>

โปรดทราบว่า solvedMessage ไม่ใช่ SettableSignal ซึ่งต่างจาก superSecretMessage ตรงที่คุณไม่สามารถเปลี่ยนค่าได้โดยตรง แต่ระบบจะอัปเดตค่าทุกครั้งที่มีการอัปเดตสัญญาณการพึ่งพา (secretMessage และ decodedCipher)

สำรวจcomputed() ฟังก์ชันอีก 2 รายการ

  • โปรดทราบว่าคุณมีค่าที่คำนวณแล้วอีก 2 ค่าในแอป

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 เป็นระบบที่คำนวณแล้ว แอปก็ควรใช้งานได้ ทดสอบฟังก์ชันการทำงานของเกม

  1. ลากและวาง LetterGuessComponent ลงใน LetterKeyComponent ใน CipherComponent เพื่อแก้ปัญหาการเข้ารหัสและถอดรหัสข้อความลับ
  2. ดูว่า SecretMessageComponent อัปเดตอย่างไรเมื่อคุณถอดรหัสข้อความลับได้มากขึ้น
  3. คลิกปรับแต่งเพื่อเปลี่ยนผู้ส่งและข้อความ แล้วคลิกสร้างและคัดลอก URL เพื่อดูค่าบนหน้าจอและการเปลี่ยนแปลง URL
  4. โบนัส: คัดลอกและวาง URL ในแท็บใหม่ หรือแชร์กับเพื่อน และดูว่าผู้ส่งและข้อความใน URL จัดเก็บอย่างไร

GIF ของเกม Angular Cypher ซึ่งมีข้อความที่ซ่อนไว้เพื่อถอดรหัสบนหน้าจอเพื่อสะกดว่า &quot;สัญญาณ Angular อยู่ในตัวอย่างสำหรับนักพัฒนาแอปในเวอร์ชัน 16 วันนี้&quot;

6. เพิ่ม effect() รายการแรก

บางครั้งคุณอาจต้องการให้การดำเนินการบางอย่างเกิดขึ้นเมื่อสัญญาณมีค่าใหม่ effect() ช่วยให้คุณกําหนดเวลาและเรียกใช้ฟังก์ชันตัวแฮนเดิลเพื่อตอบสนองต่อการเปลี่ยนแปลงของสัญญาณได้

เพิ่มกระดาษ confetti เมื่อไขรหัสสำเร็จ

เมื่อแอปใช้งานได้แล้ว คุณสามารถเพิ่มความสนุกด้วยการเพิ่มกระดาษโปรยเมื่อไขรหัสและถอดรหัสข้อความลับได้แล้ว

หากต้องการเพิ่มกระดาษโปรย ให้ทำตามขั้นตอนต่อไปนี้ในส่วนความคิดเห็น TODO(3): Add your first effect()

  1. ในไฟล์ cipher.ts ให้ตั้งเวลาเอฟเฟกต์เพื่อเพิ่มกระดาษโปรยเมื่อมีการถอดรหัสข้อความ

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 });
    }
  });
}

โปรดสังเกตว่าเอฟเฟกต์นี้ขึ้นอยู่กับสัญญาณและค่าที่คำนวณแล้ว นั่นคือ this.messages.superSecretMessage() และ this.messages.solvedMessage()

เอฟเฟกต์ช่วยให้คุณกําหนดเวลาฟังก์ชันกระดาษโปรยภายในบริบทแบบรีแอ็กทีฟเพื่อติดตามและประเมินใหม่เมื่อมีการอัปเดตทรัพยากร Dependency

ยืนยันการเปลี่ยนแปลง

  • ลองถอดรหัส (เคล็ดลับ: คุณเปลี่ยนข้อความให้สั้นลงเพื่อทดสอบได้เร็วขึ้น) ฟีเจอร์นี้จะแสดงป๊อปอัปกระดาษสีโปรยปรายเพื่อแสดงความยินดีกับ effect() รายการแรกของคุณ

GIF ของเกม Angular Cypher ที่มีข้อความที่ซ่อนอยู่ซึ่งถอดรหัสบนหน้าจอเพื่อสะกดคำว่า &quot;ถึงเวลาโปรยกระดาษสี&quot; และป๊อปเปอร์กระดาษสีจะทำงานเมื่อข้อความถูกไขแล้ว

7. ยินดีด้วย

ตอนนี้คุณก็พร้อมที่จะถอดรหัสและแชร์ข้อความลับด้วย Angular Cipher แล้ว หากมีข้อความถึงทีม Angular แท็กโซเชียลมีเดียของเราที่ @Angular เพื่อให้เราถอดรหัสได้ 🎉

เกม Angular Cypher ได้รับการแก้ไขด้วยข้อความที่ซ่อนอยู่บนหน้าจอว่า &quot;สัญญาณ Angular อยู่ในตัวอย่างสำหรับนักพัฒนาแอปในเวอร์ชัน 16 แล้ววันนี้&quot;

ตอนนี้คุณมีองค์ประกอบพื้นฐานแบบเรียลไทม์ใหม่ 3 รายการในกล่องเครื่องมือ Angular เพื่อช่วยลดความซับซ้อนในการพัฒนาและสร้างแอปที่เร็วขึ้นโดยค่าเริ่มต้น

ดูข้อมูลเพิ่มเติม

ลองดู Codelab เหล่านี้

อ่านเอกสารต่อไปนี้