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

1. قبل البدء

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

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

ما الذي ستنشئه

  • يمكنك التعرّف على العناصر الأساسية الثلاث للتفاعل التي تم تقديمها مع Angular Signals: signal() وcomputed() وeffect().
  • استخدِم إشارات Angular لتشغيل لعبة 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 أو بيئة تطوير متكامل (IDE) محلية كطريقة بديلة لتنفيذ هذا الدرس التطبيقي حول الترميز:

  1. افتح علامة تبويب جديدة في المتصفّح وانتقِل إلى https://github.com/angular/codelabs/tree/signals-get-started.
  2. يمكنك نسخ بيانات المستودع ونسخها واستخدام الأمر cd codelabs/ للانتقال إلى المستودع.
  3. اطّلِع على فرع الرمز المُعدّ مسبقًا للمبتدئين باستخدام الأمر git checkout signals-get-started.
  4. افتح الرمز في VSCode أو بيئة تطوير البرامج المتكاملة المفضّلة لديك.
  5. لتثبيت التبعيات المطلوبة لتشغيل الخادم، استخدِم الأمر npm install.
  6. لتشغيل الخادم، استخدِم الأمر ng serve.
  7. افتح علامة تبويب في المتصفّح للانتقال إلى http://localhost:4200.

3- تحديد مرجع

نقطة البداية هي لعبة Angular Cipher، ولكنها لا تعمل بعد. ستعزّز "إشارات Angular" وظائف اللعبة.

لعبة 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 are in developer preview in v16 today!"

4. حدِّد إشارة() الأولى.

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

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

تحويل superSecretMessage إلى signal()

superSecretMessage هي قيمة في MessageService تحدد الرسالة السرية التي يفكّها المشغّل. في الوقت الحالي، لا تُرسِل القيمة إشعارًا إلى التطبيق بالتغييرات، لذا لا يعمل الزر تخصيص. يمكنك حلّ هذه المشكلة باستخدام إشارة.

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

لتحديد إشارة التحذير الأولى، عليك اتّباع الخطوات التالية ضمن التعليق TODO(1): Define your first signal() في كل ملف:

  1. في ملف service.message.ts، استخدِم مكتبة "الإشارات" لجعل 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()، يمكنك التعبير بشكل صريح عن إشارة تستمدّ قيمتها من إشارات أخرى.

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

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

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

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

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

لتحويل solvedMessage إلى computed()، نفِّذ الخطوات التالية ضمن التعليق TODO(2): Define your first computed() في كل ملف:

  1. في ملف service.message.ts، استخدِم مكتبة "الإشارات" لجعل 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() لك.

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

7- تهانينا!

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

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

لديك الآن ثلاث عناصر أساسية جديدة للتفاعل في مجموعة أدوات Angular لتبسيط عملية التطوير وإنشاء تطبيقات أسرع بشكلٍ تلقائي.

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

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

اطّلِع على هذه المواد: