1. ก่อนเริ่มต้น
สัญญาณ Angular จะแนะนำพื้นฐานเชิงรับ 3 ประการใน Angular ที่คุณรู้จักและชื่นชอบ ซึ่งช่วยให้การพัฒนาของคุณง่ายขึ้นและช่วยให้คุณสร้างแอปที่เร็วขึ้นโดยค่าเริ่มต้น
สิ่งที่คุณจะสร้าง
- คุณได้เรียนรู้เกี่ยวกับพื้นฐานเชิงรับ 3 แบบที่พบในสัญญาณ Angular ได้แก่
signal()
,computed()
และeffect()
- ใช้สัญญาณ Angular เพื่อขับเคลื่อนเกม Angular Cipher การเข้ารหัสคือระบบสำหรับการเข้ารหัสและถอดรหัสข้อมูล ในเกมนี้ ผู้ใช้สามารถถอดรหัสข้อความลับด้วยการลากและวางคำใบ้เพื่อไขปริศนา ปรับแต่งข้อความ และแชร์ URL เพื่อส่งข้อความลับให้เพื่อน
ข้อกำหนดเบื้องต้น
- ความรู้เกี่ยวกับ Angular และ Typescript
- แนะนํา: ดูการทบทวนรีแอ็กชันด้วยสัญญาณเพื่อดูข้อมูลเกี่ยวกับคลังสัญญาณ Angular
2. รับโค้ด
ทุกสิ่งที่คุณต้องการสำหรับโครงการนี้อยู่ใน Stackblitz Stackblitz เป็นวิธีการที่แนะนำสำหรับการทำงานผ่าน Codelab นี้ หรือจะโคลนโค้ดแล้วเปิดโค้ดดังกล่าวในสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ที่คุณชื่นชอบก็ได้
เปิด Stackblitz และเรียกใช้แอป
หากต้องการเริ่มต้นใช้งาน ให้เปิดลิงก์ Stackblitz ในเว็บเบราว์เซอร์ที่คุณชื่นชอบ:
- เปิดแท็บเบราว์เซอร์ใหม่แล้วไปที่ https://stackblitz.com/edit/io-signals-codelab-starter?file=src%2Fcipher%2Fservice.cipher.ts,src%2Fsecret-message%2Fservice.message.ts&service.massage.ts
- แยก Stackblitz เพื่อสร้างพื้นที่ทำงานแบบแก้ไขได้ของคุณเอง Stackblitz ควรเรียกใช้แอปโดยอัตโนมัติ เพียงเท่านี้คุณก็พร้อมใช้งานแล้ว
ทางเลือก: โคลนที่เก็บและให้บริการแอป
การใช้ VSCode หรือ IDE ในเครื่องเป็นอีกวิธีหนึ่งในการทำงานผ่าน Codelab นี้
- เปิดแท็บเบราว์เซอร์ใหม่แล้วไปที่ https://github.com/angular/codelabs/tree/signals-get-started
- แยกและโคลนที่เก็บ แล้วใช้คำสั่ง
cd codelabs/
เพื่อย้ายไปยังที่เก็บ - ตรวจสอบสาขาของโค้ดเริ่มต้นด้วยคำสั่ง
git checkout signals-get-started
- เปิดโค้ดใน VSCode หรือ IDE ที่ต้องการ
- หากต้องการติดตั้งทรัพยากร Dependency ที่จำเป็นในการเรียกใช้เซิร์ฟเวอร์ ให้ใช้คำสั่ง
npm install
- หากต้องการเรียกใช้เซิร์ฟเวอร์ ให้ใช้คำสั่ง
ng serve
- เปิดแท็บเบราว์เซอร์ไปที่ http://localhost:4200
3. สร้างเกณฑ์พื้นฐาน
จุดเริ่มต้นของคุณคือเกม Angular Cipher แต่ก็ยังใช้ไม่ได้ สัญญาณ Angular จะขับเคลื่อนฟังก์ชันการทำงานของเกม
ในการเริ่มต้นใช้งาน ให้อธิบายถึงสิ่งที่คุณกำลังจะสร้างในเวอร์ชันที่เสร็จสมบูรณ์แล้ว ได้แก่ Angular Signals Cypher
- ดูข้อความที่เข้ารหัสบนหน้าจอ
- ลากและวางปุ่มตัวอักษรโดยใช้ปุ่มกดเพื่อแก้โจทย์และถอดรหัสข้อความลับ
- เมื่อดำเนินการเรียบร้อยแล้ว ให้ดูว่าข้อความอัปเดตอย่างไรเพื่อถอดรหัสข้อความลับมากขึ้น
- คลิกปรับแต่งเพื่อเปลี่ยนผู้ส่งและข้อความ จากนั้นคลิกสร้างและ คัดลอก URL เพื่อดูค่าบนหน้าจอและการเปลี่ยนแปลง URL
- โบนัส: คัดลอกและวาง URL ในแท็บใหม่ หรือแชร์กับเพื่อน และดูว่าผู้ส่งและข้อความใน URL จัดเก็บอย่างไร
4. กำหนด Signals แรก()
สัญญาณคือค่าที่สามารถบอกให้ Angular ทราบเมื่อมีการเปลี่ยนแปลง สัญญาณบางอย่างสามารถเปลี่ยนแปลงได้โดยตรง ในขณะที่สัญญาณอื่นๆ จะคำนวณค่าจากค่าของสัญญาณอื่นๆ สัญญาณเมื่อรวมกันแล้วจะสร้างกราฟของทรัพยากร Dependency โดยตรงซึ่งจะสร้างรูปแบบโฟลว์ข้อมูลในแอป
Angular ใช้การแจ้งเตือนจากสัญญาณเพื่อให้รู้ว่าต้องตรวจหาการเปลี่ยนแปลงคอมโพเนนต์ใดหรือเพื่อเรียกใช้ฟังก์ชัน effect ที่คุณกำหนด
แปลง 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 ไม่ว่าคุณจะอ่านค่าจากที่ใด ให้เรียกใช้ Getter สัญญาณ superSecretMessage()
และเมื่อใดก็ตามที่คุณเขียนค่า ให้ใช้ .set
API ใน 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()
สำรวจสัญญาณอื่นๆ อีก 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
ใหม่ได้รับการตั้งค่าอย่างไร
5. กำหนด computed() แรกของคุณ
ในหลายๆ สถานการณ์คุณอาจพบว่าตัวเองได้รับสถานะจากค่าที่มีอยู่ ควรให้อัปเดตสถานะที่ได้มาเมื่อค่าที่เกี่ยวข้องเปลี่ยนแปลง
คุณสามารถใช้ computed()
เพื่อแสดงสัญญาณที่ชัดเจนซึ่งดึงค่ามาจากสัญญาณอื่นๆ
แปลง solvedMessage
เป็น computed()
solvedMessage
จะแปลค่า secretMessage
จากที่เข้ารหัสเป็นถอดรหัสโดยใช้สัญญาณ decodedCipher
ซึ่งเป็นวิธีที่เยี่ยมมาก เพราะคุณจะเห็นว่าคุณกำลังได้รับค่าที่คำนวณตามการคำนวณอีกเครื่องหนึ่ง ดังนั้นเมื่อใดก็ตามที่สัญญาณภายในบริบทเชิงรับที่แมปไว้มีการเปลี่ยนแปลง ทรัพยากร Dependency จะได้รับแจ้ง
ขณะนี้ solvedMessage
จะไม่อัปเดตเมื่อคุณเปลี่ยน secretMessage
, decodedCipher
หรือ superSecretMessage
คุณจึงไม่เห็นการอัปเดตในหน้าจอเมื่อโปรแกรมเล่นแก้การเข้ารหัส
การกำหนดให้ solvedMessage
เป็นค่าที่คำนวณจะเป็นการสร้างบริบทเชิงรับ เพื่อให้เมื่ออัปเดตข้อความหรือแก้โจทย์การเข้ารหัส จะรับการอัปเดตสถานะจากทรัพยากร Dependency ที่ติดตามได้
หากต้องการแปลง 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>
โปรดทราบว่า solvedMessage
ไม่เหมือนกับ superSecretMessage
ตรงที่ไม่ใช่ SettableSignal
คุณจะเปลี่ยนค่าโดยตรงไม่ได้ แต่ระบบจะคอยอัปเดตค่าให้เป็นข้อมูลล่าสุดทุกครั้งที่มีการอัปเดตสัญญาณการขึ้นต่อกัน (secretMessage
และ decodedCipher
)
สำรวจอีก 2 ฟังก์ชันของ computed()
- โปรดทราบว่าคุณมีค่าที่คำนวณไว้อีก 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
เป็นระบบที่คำนวณแล้ว แอปก็ควรใช้งานได้ ทดสอบฟังก์ชันการทำงานของเกม ดังนี้
- ลากและวาง
LetterGuessComponent
ลงในLetterKeyComponent
ในCipherComponent
เพื่อแก้ปัญหาการเข้ารหัสและถอดรหัสข้อความลับ - ดูวิธีที่
SecretMessageComponent
อัปเดตเมื่อคุณถอดรหัสข้อความลับมากขึ้น - คลิกปรับแต่งเพื่อเปลี่ยนผู้ส่งและข้อความ จากนั้นคลิกสร้างและ คัดลอก URL เพื่อดูค่าบนหน้าจอและการเปลี่ยนแปลง URL
- โบนัส: คัดลอกและวาง URL ในแท็บใหม่ หรือแชร์กับเพื่อน และดูว่าผู้ส่งและข้อความใน URL จัดเก็บอย่างไร
6. เพิ่มเอฟเฟกต์แรก()
บางครั้งคุณอาจต้องการให้บางอย่างเกิดขึ้นเมื่อสัญญาณมีค่าใหม่ เมื่อใช้ effect()
คุณจะกำหนดเวลาและเรียกใช้ฟังก์ชันของเครื่องจัดการเพื่อตอบสนองต่อสัญญาณที่เปลี่ยนแปลงได้
เพิ่มกระดาษสีเมื่อแก้รหัสได้แล้ว
เมื่อแอปทำงานแล้ว ก็เพิ่มลูกเล่นสนุกๆ ได้โดยใส่แถบกระดาษสีเมื่อแก้รหัสลับได้และถอดรหัสข้อความลับแล้ว
หากต้องการเพิ่มกระดาษสี ให้ทำตามขั้นตอนต่อไปนี้ใต้ความคิดเห็น TODO(3): Add your first effect()
- กำหนดเวลาของเอฟเฟกต์เพื่อเพิ่มแถบกระดาษสีในไฟล์
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()
แรกของคุณ
7. ยินดีด้วย
Angular Cipher พร้อมถอดรหัสและแชร์ข้อความลับแล้ว หากมีข้อความถึงทีม Angular แท็กโซเชียลมีเดียของเราที่ @Angular เพื่อให้เราถอดรหัสได้ 🎉
ตอนนี้คุณมีพื้นฐานเชิงตอบสนองใหม่ 3 รายการในกล่องเครื่องมือ Angular เพื่อลดความซับซ้อนของการพัฒนาและสร้างแอปได้เร็วขึ้นโดยค่าเริ่มต้น
ดูข้อมูลเพิ่มเติม
ลองดู Codelab เหล่านี้
อ่านเนื้อหาต่อไปนี้
- Angular.io
- การทบทวนรีแอ็กชันด้วยสัญญาณต่างๆ (Google I/O 2023)
- มีอะไรใหม่ใน Angular (Google I/O 2023)