بدء استخدام "إشارات Angular"

1. قبل البدء

شعار Angular باللون الأسود

تقدّم Angular Signals ثلاث وحدات أساسية تفاعلية إلى Angular التي تعرفها وتحبّها، ما يسهّل عملية التطوير ويساعدك في إنشاء تطبيقات أسرع تلقائيًا.

ما ستنشئه

  • تتعرّف على العناصر الأساسية الثلاثة التفاعلية التي تم تقديمها مع Angular Signals: signal() وcomputed() وeffect().
  • استخدام Angular Signals لتشغيل لعبة Angular Cipher التشفير هو نظام لتشفير البيانات وفك تشفيرها. في هذه اللعبة، يمكن للمستخدمين فك ترميز رسالة سرية عن طريق سحب الأدلة وإفلاتها لحلّ شيفرة، وتخصيص الرسالة، ومشاركة عنوان URL لإرسال رسائل سرية إلى الأصدقاء.

لعبة Angular Cypher بأسلوب وحدة تحكّم ألعاب عتيقة باللون الأخضر، مع رسالة مخفية على الشاشة تقول: "Anqnxaa Lpcnaxl aaf pn jfafxyofa aofapfm pn a16 wyjak!‎"

المتطلبات الأساسية

2. الحصول على الشفرة‏

كل ما تحتاج إليه لهذا المشروع متوفّر في Stackblitz. ننصحك باستخدام Stackblitz لإكمال هذا الدرس التطبيقي حول الترميز. يمكنك بدلاً من ذلك استنساخ الرمز وفتحه في بيئة التطوير المفضّلة لديك.

افتح 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 أو بيئة تطوير متكاملة محلية كطريقة بديلة لإكمال هذا الدرس التطبيقي حول الترميز:

  1. افتح علامة تبويب متصفّح جديدة وانتقِل إلى https://github.com/angular/codelabs/tree/signals-get-started.
  2. أنشئ نسخة طبق الأصل من المستودع واستنسخه، واستخدِم الأمر cd codelabs/ للانتقال إلى المستودع.
  3. راجِع فرع الرمز الأولي باستخدام الأمر git checkout signals-get-started.
  4. افتح الرمز في VSCode أو بيئة التطوير المتكاملة (IDE) المفضّلة لديك.
  5. لتثبيت التبعيات المطلوبة لتشغيل الخادم، استخدِم الأمر 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 في الإصدار 16 اليوم في معاينة للمطوّرين"

4. تحديد أول إشارة()

الإشارة هي قيمة يمكنها إخبار Angular عند تغيُّرها. يمكن تغيير بعض الإشارات مباشرةً، بينما تحسب إشارات أخرى قيمها من قيم إشارات أخرى. تنشئ الإشارات معًا رسمًا بيانيًا موجّهًا للاعتمادات يوضّح كيفية تدفّق البيانات في تطبيقك.

يمكن أن تستخدم Angular الإشعارات من الإشارات لمعرفة المكوّنات التي يجب رصد التغييرات فيها أو لتنفيذ وظائف التأثير التي تحدّدها.

تحويل 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. أينما قرأت القيمة، استدعِ دالة الحصول على الإشارة superSecretMessage(). وأينما تكتب القيمة، استخدِم واجهة برمجة التطبيقات .set على 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()

استكشاف الإشارتَين الأخريَين

  • لاحظ أنّ لديك إشارتَين أخريَين في تطبيقك:

src/app/cipher/service.cipher.ts

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

تحدّد CipherService إشارة cipher، وهي عبارة عن ربط عشوائي بين أزواج المفتاح/القيمة المكوّنة من حرف واحد من الأبجدية وحرف cipher جديد. يتم استخدام هذا الإجراء لتشفير الرسالة وتحديد ما إذا كان اللاعب سيجد تطابقًا ناجحًا على لوحة المفاتيح.

لديك أيضًا إشارة decodedCipher لأزواج المفاتيح والقيم التي تم فك تشفيرها بنجاح والتي ستضيفها عندما يحلّ اللاعب الشفرة.

من السمات الفريدة والفعّالة لتصميم مكتبة Signals في Angular أنّه يمكنك إدخال التفاعلية في كل مكان. لقد حدّدت الإشارات مرة واحدة في خدمات التطبيق، ويمكنك استخدامها في نموذج أو مكوّنات أو أنابيب أو خدمات أخرى أو في أي مكان يمكنك كتابة الرمز البرمجي للتطبيق فيه. ولا تكون محدودة أو مرتبطة بنطاق أحد المكوّنات.

التحقّق من التغييرات

  • يجب اتّخاذ خطوة أخرى قبل أن يعمل التطبيق. في الوقت الحالي، جرِّب إضافة console.log() في أجزاء مختلفة من تطبيقك لمعرفة كيفية ضبط superSecretMessage الجديد.

‫Stackblitz مع رسالة console.log() تعرض رسالة superSecretMessage تسجّل الرسالة الجديدة بشكل صحيح

5- تحديد أول دالة computed()

في العديد من الحالات، قد تجد نفسك تستمد الحالة من القيم الحالية. من الأفضل تعديل الحالة المشتقة عند تغيُّر القيمة التابعة.

باستخدام computed()، يمكنك التعبير بشكل تصريحي عن إشارة تستمد قيمتها من إشارات أخرى.

تحويل solvedMessage إلى computed()

تحوّل solvedMessage قيمة secretMessage من ترميز إلى فك ترميز باستخدام إشارة decodedCipher.

هذا أمر رائع لأنّه يمكنك ملاحظة أنّك تستمد قيمة محسوبة من قيمة محسوبة أخرى، وبالتالي في كل مرة يتغيّر فيها عنصر في سياق التفاعل الذي تم ربطه، يتم إعلام العناصر التابعة.

في الوقت الحالي، لا يتم تعديل solvedMessage عند تغيير secretMessage أو decodedCipher أو superSecretMessage. لذلك، لن تظهر لك أي تحديثات على الشاشة عندما يحلّ اللاعب الشفرة.

من خلال جعل solvedMessage قيمة محسوبة، يمكنك إنشاء سياق تفاعلي حتى تتمكّن عند تعديل الرسالة أو حلّ الرمز من استخلاص تعديل الحالة من الاعتماديات التي يتم تتبّعها.

لتحويل 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>

يُرجى العِلم أنّه على عكس superSecretMessage، فإنّ solvedMessage ليس SettableSignal، ولا يمكنك تغيير قيمته مباشرةً. بدلاً من ذلك، يتم تعديل قيمتها باستمرار كلما تم تعديل أي من إشارتَي الاعتمادية (secretMessage وdecodedCipher).

استكشاف computed() الدالتَين الأخريَين

  • لاحظ أنّ لديك قيمتين محسوبتين أخريين في تطبيقك:

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 Signals في الإصدار 16 اليوم في معاينة للمطوّرين&quot;

6. إضافة أول تأثير()

في بعض الأحيان، قد تريد أن يحدث شيء ما عندما تتلقّى إشارة قيمة جديدة. باستخدام effect()، يمكنك جدولة دالة معالجة وتشغيلها استجابةً لتغيير الإشارات.

إضافة قصاصات ورق ملوّنة عند حلّ الشفرة

بعد أن أصبح التطبيق يعمل، يمكنك إضافة بعض المرح من خلال إضافة قصاصات ورقية متطايرة عند حلّ الشيفرة وفك تشفير الرسالة السرية.

لإضافة قصاصات ورق ملوّنة، اتّبِع الخطوات التالية ضمن التعليق 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().

تساعدك الدالة Effect في جدولة وظيفة قصاصات الورق الملوّنة داخل سياق تفاعلي لتتبُّع وإعادة تقييم وقت تعديل العناصر التابعة.

التحقّق من التغييرات

  • حاوِل حلّ الشفرة (ملاحظة: يمكنك تغيير الرسالة إلى رسالة قصيرة لاختبارها بشكل أسرع). ستظهر قصاصات ملونة لتهنئتك على إكمال أول effect().

صورة GIF للعبة Angular Cypher، مع فك تشفير رسالة مخفية على الشاشة لتظهر كلمة &quot;حان وقت الاحتفال&quot;، وانطلاق قصاصات ملونة عند حل الرسالة.

7. تهانينا!

أصبحت أداة Angular Cipher جاهزة الآن لفك تشفير الرسائل السرية ومشاركتها. هل لديك رسالة لفريق Angular؟ يمكنك الإشارة إلى حساباتنا على وسائل التواصل الاجتماعي من خلال @Angular لنتمكّن من فكّ رموزها. 🎉

تم حلّ لعبة Angular Cypher باستخدام رسالة مخفية على شاشة &quot;إصدار تجريبي من Angular Signals للمطوّرين في الإصدار 16 اليوم!&quot;

تتوفّر الآن ثلاث وحدات أساسية تفاعلية جديدة في مجموعة أدوات Angular لتسهيل عملية التطوير وإنشاء تطبيقات أسرع تلقائيًا.

مزيد من المعلومات

اطّلِع على دروس الترميز التطبيقية التالية:

اطّلِع على المواد التالية: