محتويات الدورة

Angular / الأساسي / الدرس 5

المدخلات والمخرجات والتركيب

امنح المكوّن عقدًا صغيرًا: يستقبل البيانات ويصدر النية ويقرر المالك تغيير الحالة المشتركة.

وقت القراءة التقريبي: 3 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • تعريف مدخلات إشارة لازمة ومخرجات محددة النوع.
  • فصل ملكية الحالة من عرض الفرعي.
  • اختبار تغير المدخل وإصدار النية عند المستهلك.

يعرض الفرعي تفاعلًا متماسكًا

يصف المدخل بيانات الوالد والمخرج حدث الفرعي. يفصل ذلك الملكية والعرض ويمنع تعديلًا خفيًا لكائن الوالد. سمِّ النية مثل selected بدل آلية متصفح غامضة. تُقرأ إشارة المدخل وتدخل في computed. يعلن المدخل اللازم عقدًا للفاحص، وتظل قراءته قبل تعيين Angular خطأ دورة حياة. أظهر الفروض بدل تأكيد الغياب.

فحص انتقال المالك مستقلًا

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

typescript نموذج مكتمل لانتقال المالك
export {};
class SelectionModel {
  selectedId: number | undefined;
  select(id: number): void {
    if (!Number.isSafeInteger(id) || id < 1) { throw new Error("invalid id"); }
    this.selectedId = id;
  }
}
const owner = new SelectionModel();
owner.select(2);
console.log(owner.selectedId);
try { owner.select(0); } catch { console.log("rejected"); }
الناتج المتوقع
2
rejected

يطبع النموذج اثنين وrejected ولا ينشئ مكوّنًا أو يصدر حدث Angular.

التصريح بالبيانات والنية عند حد الفرعي

يستخدم الفرعي input.required للهوية والعنوان وoutput<number> للاختيار. يقرأ القالب المدخلات ويصدر الهوية ويبقى التغيير عند الوالد. تتعرف ترجمة Angular على مهيئ output، وليس ناقل أحداث عامًا، ولا تتصاعد المخرجات كأحداث DOM. يحتاج المقطع تهيئة ومضيفًا يقدم اللازم؛ فلا تنشئ الصنف مباشرة وتفترض ملء المدخل.

typescript فرعي سياقي ببيانات لازمة ونية محددة
import { Component, input, output } from "@angular/core";
@Component({
  selector: "app-course-option", standalone: true,
  template: `<button type="button" (click)="selected.emit(courseId())">{{ title() }}</button>`
})
export class CourseOption {
  readonly courseId = input.required<number>();
  readonly title = input.required<string>();
  readonly selected = output<number>();
}

يقدم المضيف الصحيح courseId وtitle ويصدر الزر الهوية عند التفعيل، ولا يُدّعى تنفيذ التفعيل هنا.

جعل قالب المستهلك يملك التوصيل

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

html ربط والد سياقي بعد استيراد CourseOption
<app-course-option
  [courseId]="course.id"
  [title]="course.title"
  (selected)="onSelected($event)" />

يقدم الوالد مقررًا ويستقبل هويته، ويحتاج المقطع صنفه واستيراداته ومضيفه فلا يستقل بالتشغيل.

اختبار العقد كما يستخدمه المستهلك

استخدم مضيف اختبار يقدم المدخل ويغيره ويستمع للمخرج، وافحص اسم الزر والهوية وحالة الوالد. لا يثبت اختبار الصنف الأسلاك. تكشف الترجمة المدخل المفقود وتحتاج HTTP أو المصادر غير المكتوبة فحصًا فعليًا. تجنب أسماء تلتبس بأحداث DOM ووثّق هل يصدر الفرعي نية أو يؤدي عملًا قد يفشل. تحمي الحدود إعادة الاستخدام من متحكم عام خفي.

الأخطاء الشائعة وإصلاحها

قراءة مدخل لازم قبل تعيينه.

لماذا يحدث؟
خُلط بناء الصنف باكتمال المدخلات.
كيف تصلحه؟
اقرأه في سياق تفاعلي أو دورة حياة مناسبة.
كيف تتجنب تكراره؟
اختبر تعيين Angular لا الإنشاء المباشر وحده.

يغير الفرعي بيانات الوالد دون حدث واضح.

لماذا يحدث؟
حل تعديل مشترك محل الملكية الصريحة.
كيف تصلحه؟
أصدر النية ودع المالك يطبّق الانتقال.
كيف تتجنب تكراره؟
وثّق التعديل في الواجهة.

توقع تصاعد المخرج لسلف بعيد.

لماذا يحدث؟
عوملت المخرجات كأحداث DOM متصاعدة.
كيف تصلحه؟
اربط صراحة أو استخدم تنسيق خدمة مناسبًا.
كيف تتجنب تكراره؟
اختبر حد المستهلك الفعلي.

اختبر فهمك

1. يصدر خيار ثانٍ الهوية ثلاثة. كيف يتغير الوالد وما ملاحظة الاختبار؟

اعرض الحل المشروح

يفحص الوالد ثلاثة ويستبدل الاختيار وفق القاعدة. فعّل زر الفرعي الثاني وافحص المخرج وحالة الوالد وعدم تعديل مدخل الأول. يحمي النموذج المحلي الانتقال وحده، فاحتفظ بالدليلين.

2. يتلقى الوالد courseId نصًا من HTTP غير مفحوصة. هل تحوله input.required<number>()؟

اعرض الحل المشروح

لا؛ يفيد النوع الفحص ولا يحلل الاستجابة الاعتباطية. افحص وطبع القيمة بسياسة قبل النموذج وارفض المشوه أو غير المصرح واختبره. لا تؤكد أن النص عدد فقط.

أهم ما تعلمته

  • تقدم المدخلات بيانات والمخرجات نية.
  • أظهر ملكية الحالة.
  • افحص العقد عبر المضيف.

المراجع الرسمية