في تطوير المشروع الزاوي، نستخدم عادةً ربط خاصية الإدخال وربط حدث الإخراج لاتصال المكونات، ومع ذلك، لا يمكن استخدام الإدخال والإخراج إلا في الوالدين والطفل مكونات نقل المعلومات. تشكل المكونات شجرة مكونات بناءً على علاقة الاستدعاء، إذا كانت هناك روابط خصائص وروابط أحداث فقط، فيجب أن يتواصل مكونان غير مباشرين من خلال كل نقطة اتصال نفسها، ويحتاج الوسيط إلى معالجة بعض الأشياء التي يقوم بها وتمريرها بشكل مستمر لا تحتاج إلى معرفة المعلومات (الشكل 1 اليسار). يمكن توفير الخدمة القابلة للحقن المقدمة في Angular في وحدات أو مكونات أو تعليمات، ويمكن دمجها مع الحقن في المُنشئ، لحل هذه المشكلة (مباشرة في الشكل 1). [البرامج التعليمية الموصى بها: "البرنامج التعليمي الزاوي"]
الشكل 1: نموذج اتصال المكونات
تنقل الصورة اليسرى المعلومات فقط من خلال المكونات الأصلية والفرعية، وتحتاج العقدة a والعقدة b إلى المرور عبر العديد من العقد للتواصل، وإذا أرادت العقدة c التحكم في العقدة b من خلال بعض التكوينات، فيجب تعيين العقد بينهما أيضًا سمات أو أحداث إضافية لنقل المعلومات المقابلة بشفافية. يمكن أن توفر العقدة c في وضع حقن التبعية في الصورة على اليمين خدمة للعقدتين a وb للتواصل مباشرة مع الخدمة التي تقدمها العقدة c، وتتواصل العقدة b أيضًا بشكل مباشر مع الخدمة المقدمة من العقدة c. أخيرًا، تم تبسيط الاتصال، ولم تقترن العقدة الوسطى بهذا الجزء من المحتوى، وليس لديها وعي واضح بالاتصال الذي يحدث بين المكونات العلوية والسفلية.
لا يعد حقن التبعية (DI) فريدًا بالنسبة إلى Angular، بل هو وسيلة لتنفيذ نمط تصميم انعكاس التحكم (IOC). يؤدي ظهور حقن التبعية إلى حل مشكلة الاقتران اليدوي الزائد إنشاء مثيل، ولا يمكن استخدام جميع الموارد من قبل كلا الطرفين، بدلاً من توفيرها من قبل مراكز الموارد أو الجهات الخارجية التي لا تستخدم الموارد، يمكن أن تحقق العديد من الفوائد. أولاً، الإدارة المركزية للموارد تجعل الموارد قابلة للتكوين وسهلة الإدارة. ثانيًا: أنه يقلل من درجة الاعتماد بين الطرفين باستخدام الموارد، وهو ما نسميه الاقتران.
تشبيهًا بالعالم الحقيقي هو أننا عندما نشتري منتجًا مثل قلم الرصاص، نحتاج فقط إلى العثور على متجر لشراء منتج من نوع قلم الرصاص. نحن لا نهتم بمكان إنتاج قلم الرصاص أو كيف يؤدي الخشب والقلم الرصاص نحن بحاجة إليها فقط لإكمال وظيفة الكتابة بالقلم الرصاص. ولن يكون لدينا أي اتصال مع الشركة المصنعة أو المصنع المحدد للقلم الرصاص. أما بالنسبة للمتجر، فيمكنه شراء أقلام الرصاص من القنوات المناسبة وتحقيق إمكانية تكوين الموارد.
بالاشتراك مع سيناريو الترميز، وبشكل أكثر تحديدًا، لا يحتاج المستخدمون إلى إنشاء مثيلات (عمليات جديدة) بشكل صريح لإدخال المثيلات واستخدامها. يتم تحديد إنشاء المثيلات بواسطة الموفرين. تتم إدارة الموارد من خلال الرموز المميزة نظرًا لأنها لا تهتم بالموفر أو إنشاء المثيلات، فيمكن للمستخدم استخدام بعض طرق الحقن المحلية (التكوين الثانوي للرموز المميزة) لتحقيق استبدال المثيل ووضع حقن التبعية والبرمجة الجانبية (AOP ) يكمل كل منهما الآخر.
يعد حقن التبعية أحد أهم الوحدات الأساسية للإطار الزاوي، ولا يوفر Angular حقن نوع الخدمة فحسب، بل إن شجرة المكونات نفسها عبارة عن شجرة تبعية للحقن، ويمكن أيضًا حقن الوظائف والقيم. وهذا يعني أنه في إطار العمل Angular، يمكن للمكونات الفرعية حقن مثيلات المكون الأصلي من خلال الرمز المميز للمكون الأصلي (عادةً اسم الفئة). في تطوير مكتبة المكونات، هناك عدد كبير من الحالات التي يتم فيها تحقيق التفاعل والتواصل عن طريق حقن المكونات الأصلية، بما في ذلك تركيب المعلمات، ومشاركة الحالة، وحتى الحصول على DOM للعقدة التي يوجد بها المكون الأصلي، وما إلى ذلك.
لاستخدام الحقن الزاوي، يجب عليك أولاً فهم عملية دقة الحقن الخاصة به. على غرار عملية تحليل وحدات العقدة، عندما لا يتم العثور على تبعيات، ستنتقل التبعيات دائمًا إلى الطبقة الأصلية للعثور على التبعيات. يقسم الإصدار القديم من Angular (قبل الإصدار السادس) عملية تحليل الحقن إلى حاقنات وحدة متعددة المستويات، وحاقن مكونات متعددة المستويات، وحاقن عناصر. تم تبسيط الإصدار الجديد (بعد الإصدار 9) إلى نموذج من مستويين. سلسلة الاستعلام الأولى هي حاقن عنصر مستوى DOM الثابت، وحاقن المكونات، وما إلى ذلك، والتي تسمى مجتمعة حاقنات العناصر، وسلسلة الاستعلام الأخرى هي حاقن الوحدة. يتم شرح ترتيب التحليل والقيمة الافتراضية بعد فشل التحليل بشكل أكثر وضوحًا في مستند التعليق الرسمي على الكود (provider_flag).
الشكل 2 تعني عملية البحث عن التبعيات للحاقن ثنائي المستوي (مصدر الصورة)
أن المكونات/التعليمات وتوفير المحتوى المحقون على مستوى المكون/التعليمات سوف يبحث أولاً عن التبعيات في العناصر الموجودة في عرض المكون وصولاً إلى العنصر الجذر إذا لم يتم العثور عليه، في عنصر الوحدة النمطية الحالية، يتم البحث عن المرجع (بما في ذلك مرجع الوحدة ومرجع التحميل البطيء للتوجيه) للوحدة الأصلية للوحدة حتى الوحدة الجذرية ووحدة النظام الأساسي.
لاحظ أن الحاقن هنا له وراثة، ويمكن لحاقن العنصر إنشاء ووراثة وظيفة البحث لحاقن العنصر الأصلي، وحاقن الوحدة مشابه. بعد الميراث المستمر، يصبح الأمر أشبه بسلسلة النموذج الأولي لكائنات js.
يفهم موفرو التكوين ترتيب أولويات حل التبعية، ويمكننا توفير المحتوى على المستوى المناسب. نحن نعلم بالفعل أنه يأتي في نوعين: حقن الوحدة وحقن العناصر.
حاقن الوحدة النمطية: يمكن تكوين الموفرين في سمة البيانات التعريفية لـ @NgModule، ويمكنك أيضًا استخدام عبارة @Injectable المقدمة بعد الإعلان عن الإصدار v6 كاسم الوحدة، "الجذر"، وما إلى ذلك. (في الواقع، يوجد حاقنان فوق الوحدة الجذرية، Platform وNull. لن يتم مناقشتهما هنا.)
حاقن العنصر: يمكن تكوين الموفرين، viewProviders في سمة البيانات التعريفية للمكون @Component، أو في @ للتوجيه
بالإضافة إلى ذلك، في الواقع، بالإضافة إلى استخدام حاقن الوحدة المُعلن عنه، يمكن أيضًا الإعلان عن مصمم الديكور @Injectable باعتباره حاقنًا للعناصر
.
في كثير من الأحيان سيتم الإعلان عنه على أنه منصوص عليه في الجذر لتنفيذ مفردة. فهو يدمج البيانات الوصفية من خلال الفئة نفسها لتجنب الوحدات أو المكونات التي تعلن بشكل صريح عن الموفر. وبهذه الطريقة، إذا لم يكن لدى الفئة أي خدمة توجيه مكون وفئات أخرى لإدخالها، فلن يكون هناك رمز مرتبط بإعلان النوع. يمكن للمترجم تجاهله، وبالتالي تحقيق هز الشجرة.
هناك طريقة أخرى لتوفيرها وهي إعطاء القيمة مباشرة عند الإعلان عن حقنة.
فيما يلي القوالب المختصرة لهذه الطرق:
@NgModule({ Providers: [ // حاقن الوحدة] }) فئة التصدير MyModule {}
@Component({ مقدمو الخدمات: [ // حاقن العنصر - المكون]، مقدمو العرض: [ // حاقن العنصر - عرض المكون] }) فئة التصدير MyComponent {}
@Directive({ مقدمو الخدمة: [ // حاقن العنصر - التوجيه] }) فئة التصدير MyDirective {}
@Injectable({ المقدمة في: 'الجذر' }) فئة التصدير MyService {}
Export const MY_INJECT_TOKEN = new حقنToken<MyClass>('my-inject-token', { المقدمة في: 'الجذر'، المصنع: () => { إرجاع MyClass() الجديد; } });
ستؤدي الخيارات المختلفة لتوفير مواقع التبعيات إلى ظهور بعض الاختلافات، مما يؤثر في النهاية على حجم الحزمة، والنطاق الذي يمكن إدخال التبعيات فيه، ودورة حياة التبعيات. هناك حلول مختلفة قابلة للتطبيق لسيناريوهات مختلفة، مثل المفرد (الجذر)، وعزل الخدمة (الوحدة النمطية)، ونوافذ التحرير المتعددة (المكون)، وما إلى ذلك. يجب عليك اختيار موقع معقول لتجنب المعلومات المشتركة غير المناسبة أو تعبئة التعليمات البرمجية الزائدة عن الحاجة.
توفر فقط حقن المثيلات، فلن تظهر مرونة حقن التبعية للإطار الزاوي. يوفر Angular العديد من أدوات الحقن المرنة. ينشئ useClass تلقائيًا مثيلات جديدة، ويستخدم useValue قيمًا ثابتة، ويمكن لـ useExisting إعادة استخدام المثيلات الموجودة، ويتم إنشاء useFactory من خلال وظائف، مع deps محددة ومعلمات مُنشئة محددة. يمكنك قطع الرمز المميز للفئة واستبداله بمثيل آخر قمت بإعداده. يمكنك إنشاء رمز مميز لحفظ القيمة أو المثيل أولاً، ثم استبداله مرة أخرى عندما تحتاج إلى استخدامه لاحقًا يتم تعيين وظيفة المصنع لإعادتها، ويتم تعيين المعلومات المحلية للمثيل إلى كائن أو قيمة سمة أخرى. سيتم شرح طريقة اللعب هنا من خلال الحالات التالية، لذلك لن أخوض فيها هنا. يحتوي الموقع الرسمي أيضًا على العديد من الأمثلة كمرجع.
يمكن حقن الحقن في Angular داخل المنشئ، أو يمكنك الحصول على الحاقن للحصول على العناصر المحقونة الموجودة من خلال طريقة get.
يدعم Angular إضافة أدوات تزيين لوضع علامة عليها عند الحقن،
، هناك مقال "@Self أو @Optional @Host؟ الدليل المرئي لمصممي Angular DI." والذي يوضح بوضوح شديد أنه إذا تم استخدام أدوات تزيين مختلفة بين المكونات الأصلية والتابعة، فإن الأمثلة التي سيتم ضربها في النهاية هي: يا لها من اختلاف.
الشكل 3 تصفية نتائج الديكورات المحقونة المختلفة
من بين عرض المضيف ومصممي @Host، قد يكون @Host هو الأكثر صعوبة في الفهم، فيما يلي بعض الإرشادات المحددة لـ @Host. التفسير الرسمي لمصمم @Host هو
...استرجاع التبعية من أي حاقن حتى الوصول إلى عنصر المضيف.
المضيف هنا يعني أن مصمم الديكور @Host سوف يحد من نطاق الاستعلام داخل العنصر المضيف. ما هو العنصر المضيف؟ إذا كان المكون B عبارة عن مكون يستخدمه قالب المكون A، فإن مثيل المكون A هو العنصر المضيف لمثيل المكون B. يُطلق على المحتوى الذي تم إنشاؤه بواسطة قالب المكون اسم العرض. وقد تكون طريقة العرض نفسها طرق عرض مختلفة لمكونات مختلفة. إذا كان المكون A يستخدم المكون B ضمن نطاق القالب الخاص به (انظر الشكل 4)، فإن العرض (جزء المربع الأحمر) الذي يتكون من محتوى قالب A هو العرض المضمن للمكون A، والمكون B موجود ضمن طريقة العرض هذه، لذلك بالنسبة إلى B ، هذا العرض هو عرض مضيف B. يقوم الديكور @Host بتقييد نطاق البحث بعرض المضيف. إذا لم يتم العثور عليه، فلن يظهر.
الشكل 4 العرض المضمن وعرض المضيف
دعنا نستخدم حالات حقيقية لمعرفة كيفية عمل حقن التبعية، وكيفية استكشاف الأخطاء وإصلاحها، وكيفية اللعب.
يوفر مكون النافذة المشروط لمكتبة مكونات DevUI خدمة ModalService، والتي يمكن أن تظهر مربعًا مشروطًا ويمكن تهيئتها كمكون مخصص. غالبًا ما يبلغ طلاب الأعمال عن الأخطاء عند استخدام هذا المكون، قائلين إن الحزمة لا يمكنها العثور على المكون المخصص.
على سبيل المثال، تم الإبلاغ عن الخطأ التالي:
الشكل 5 عند استخدام ModalService، يوجد خطأ عند إنشاء مكون يشير إلى EditorX. لا يمكن العثور على موفر الخدمة المقابل.
قم بتحليل كيفية إنشاء ModalService للمكونات المخصصة. كما ترون، إذا لم يتم تمرير componentFactoryResolver
، فسيتم استخدام componentFactoryResolver
الذي تم حقنه بواسطة ModalService. في معظم الحالات، ستقدم الشركة DevUIModule مرة واحدة في الوحدة الجذرية، ولكنها لن تقدم ModalModule في الوحدة الحالية. أي أن الوضع الحالي في الشكل 6 هو على هذا النحو. وفقًا للشكل 6، لا يوجد EditorXModuleService في محقن ModalService.
الشكل 6: مخطط علاقة توفير خدمة الوحدة النمطية
وفقًا لميراث الحاقن، هناك أربعة حلول:
ضع EditorXModule حيث تم الإعلان عن ModalModule، حتى يتمكن الحاقن من العثور على EditorModuleService المقدم من EditorXModule - وهذا هو الحل الأسوأ، وقد تم تنفيذ التحميل البطيء نفسه بواسطة LoadChildren هو تقليل تحميل وحدة الصفحة الرئيسية، والنتيجة هي أن المحتوى الذي يجب استخدامه في الصفحة الفرعية يتم وضعه في AppModule، ويتم تحميل وحدة النص المنسق الكبيرة عند التحميل الأول، مما يؤدي إلى تفاقم المشكلة FMP (الطلاء الأول ذو المعنى) لا ينبغي أن يؤخذ.
قم بتقديم ModalService في الوحدة التي تقدم EditorXModule وتستخدم ModalService - فمن المستحسن. هناك موقف واحد فقط لا يُنصح به، وهو أن استدعاء ModalService هو خدمة عامة أخرى عالية المستوى، والتي لا تزال تضع وحدات غير ضرورية على الطبقة العليا للتحميل.
عند تشغيل المكون باستخدام ModalService، قم بإدخال componentFactoryResolver
الخاص بالوحدة النمطية الحالية وتمريره إلى معلمة الوظيفة المفتوحة لـ ModalService - يُنصح بتقديم EditorXModule حيث يتم استخدامه بالفعل.
في الوحدة المستخدمة، يُنصح بتوفير خدمة ModalService يدويًا، والتي تحل مشكلة إدخال البحث.
تعمل الطرق الأربع في الواقع على حل مشكلة EditorXModuleService في السلسلة الداخلية لحاقن componentFactoryResolver
الذي تستخدمه ModalService. ومن خلال التأكد من أن سلسلة البحث على مستويين يمكن حل هذه المشكلة.
ملخص نقاط المعرفة : وراثة حاقن الوحدة ونطاق البحث.
عادةً عندما نستخدم نفس القالب في أماكن متعددة، سنقوم باستخراج الجزء المشترك من خلال القالب. عندما تم تطوير مكون DevUI Select من قبل، أراد المطور استخراج الجزء المشترك والإبلاغ عن خطأ خطأ.
الشكل 7: لم يتم العثور على خطأ في حركة الكود والحقن،
وذلك لأن تعليمات CdkVirtualScrollFor تحتاج إلى إدخال CdkVirtualScrollViewport، ومع ذلك، يرث نظام وراثة حاقن العنصر علاقة DOM الثابتة، وبالتالي فإن العلاقة الديناميكية غير ممكنة يحدث سلوك الاستعلام التالي، ويفشل البحث.
الشكل 8: الحل النهائي لنطاق البحث عن سلسلة الاستعلام عن العنصر
: إما 1) الحفاظ على موضع الكود الأصلي دون تغيير، أو 2) تحتاج إلى تضمين القالب بأكمله للعثور عليه.
الشكل 9: يؤدي تضمين الوحدة بأكملها إلى تمكين CdkVirtualScrollFo من العثور على CdkVirtualScrollViewport (الحل 2)
ملخص نقاط المعرفة : سلسلة الاستعلام الخاصة بحاقن العنصر هي أصل عنصر DOM للقالب الثابت.
تأتي هذه الحالة من هذه المدونة "Angular: نموذج متداخل للقالب".
لقد واجهنا أيضًا نفس المشكلة عند استخدام التحقق من صحة النموذج. كما هو موضح في الشكل 10، نقوم، لبعض الأسباب، بتغليف عناوين الحقول الثلاثة في مكون لإعادة الاستخدام.
الشكل 10: قم بتغليف حقول العناوين الثلاثة للنموذج في مكون فرعي
في هذا الوقت، سنجد أنه تم الإبلاغ عن خطأ يتطلب ngModelGroup
وجود ControlContainer
داخل المضيف، وهو المحتوى المقدم بواسطة توجيه ngForm.
الشكل 11: لا يمكن لـ ngModelGroup العثور على ControlContainer.
بالنظر إلى كود ngModelGroup، يمكنك أن ترى أنه يضيف فقط قيود الديكور المضيف.
الشكل 12: يحد ng_model_group.ts من نطاق حقن ControlContainer.
هنا يمكنك استخدام viewProvider مع useExisting لإضافة موفر ControlContainer إلى عرض المضيف الخاص بـ AddressComponent.
الشكل 13 استخدام viewProviders لتوفير
نقاط معرفة الموفر الخارجية للمكونات المتداخلة ملخص نقاط المعرفة: الاستخدام الرائع لـ viewProvider واستخدامExisting.
التحميل البطيء، مما أدى إلى عدم القدرة على السحب والإسقاط لبعضها البعض في منصة الأعمال الداخلية عند تحميل LoadChildren، سيتم تجميع كل وحدة نمطية DragDropModule لمكتبة مكونات DevUI بشكل منفصل، وتوفر هذه الوحدة خدمة DragDropService. تنقسم تعليمات السحب والإفلات إلى تعليمات قابلة للسحب وتعليمات قابلة للإسقاط، وتتواصل الإرشادات من خلال DragDropService. في الأصل، كان من الممكن التواصل عن طريق تقديم نفس الوحدة واستخدام الخدمة التي تقدمها الوحدة، ومع ذلك، بعد التحميل البطيء، تمت تعبئة وحدة DragDropModule مرتين، مما أدى أيضًا إلى حالتين معزولتين. في هذا الوقت، لا يمكن للتعليمات القابلة للسحب في الوحدة النمطية المحملة البطيئة التواصل مع التعليمات القابلة للسحب في وحدة نمطية أخرى محملة البطيئة، لأن DragDropService ليست هي نفس المثيل في هذا الوقت.
الشكل 14 يؤدي التحميل البطيء للوحدات إلى عدم كون الخدمات هي نفس المثيل/الحالة الفردية.
من الواضح أن متطلباتنا هنا هي أننا نحتاج إلى وحدة مفردة، وعادةً ما تكون طريقة المفردة providerIn: 'root'
هل من الجيد توفير خدمة DragDropService لمكتبة المكونات مباشرة على مستوى الوحدة؟ لكن إذا فكرت في الأمر بعناية، فستجد هنا مشاكل أخرى. يتم توفير مكتبة المكونات نفسها للاستخدام من قبل مجموعة متنوعة من الشركات. إذا كان لدى بعض الشركات مجموعتي سحب وإفلات متطابقتين في مكانين على الصفحة، فهي لا تريد أن يتم ربطها. في هذا الوقت، يقوم المفرد بتدمير العزلة الطبيعية بناءً على الوحدة.
عندها سيكون من المعقول أكثر تنفيذ الاستبدال المفرد من جانب الأعمال. تذكر سلسلة استعلام التبعية التي ذكرناها سابقًا، يتم البحث عن حاقن العنصر أولاً. إذا لم يتم العثور عليه، فسيتم تشغيل حاقن الوحدة. لذا فإن فكرة الاستبدال هي أنه يمكننا توفير موفري مستوى العناصر.
الشكل 15 استخدم طريقة الامتداد للحصول على خدمة DragDropService جديدة ووضع علامة عليها كما هو منصوص عليه في مستوى الجذر
الشكل 16 يمكنك استخدام نفس المحدد لتركيب التعليمات المتكررة، وتركيب تعليمات إضافية على التعليمات القابلة للسحب والتعليمات القابلة للإسقاط لمكتبة المكونات، واستبدال الرمز المميز لـ DragDropService بـ DragDropGlobalService الذي قدم مفردًا في الجذر
كما هو موضح في الشكلان 15 و16، نقوم بإدخال العناصر من خلال المعالج الذي يقوم بتركيب التعليمات واستبدال رمز DragDropService بمثيل من المفرد العالمي الخاص بنا. في هذا الوقت، حيث نحتاج إلى استخدام خدمة DragDropService المفردة العامة، نحتاج فقط إلى تقديم الوحدة التي تعلن وتصدر هاتين التعليمات الإضافية لتمكين التعليمات القابلة للسحب، التعليمات القابلة للإسقاط لمكتبة المكونات من التواصل عبر الوحدات النمطية المحملة ببطء.
ملخص نقاط المعرفة : تتمتع حاقنات العناصر بأولوية أعلى من حاقنات الوحدة النمطية.
تستخدم سمات مكتبة مكونات DevUI سمات CSS المخصصة (متغيرات CSS) للإعلان عن قيمة متغير CSS للجذر لتحقيق تبديل السمة. . إذا أردنا عرض معاينات لموضوعات مختلفة في نفس الوقت في واجهة واحدة، فيمكننا إعادة تعريف متغيرات CSS محليًا في عنصر DOM لتحقيق وظيفة السمات المحلية. عندما كنت أقوم بإنشاء منشئ ثبات السمات من قبل، استخدمت هذه الطريقة لتطبيق سمة محليًا.
الشكل 17: وظيفة السمة المحلية
، ولكن لا يكفي تطبيق قيم متغيرات CSS محليًا. هناك بعض الطبقات المنبثقة المنسدلة المرتبطة بالجزء الخلفي من الجسم بشكل افتراضي، مما يعني أن الطبقة المرفقة الخاصة بها موجودة في الخارج. المتغيرات المحلية، الأمر الذي سيؤدي إلى مشكلة محرجة للغاية. يعرض المربع المنسدل لمكون السمة المحلية نمط السمة الخارجية.
الشكل 18 يتم إرفاق المكون الموجود في السمة المحلية بالمربع المنسدل للتراكب الخارجي.
ماذا علي أن أفعل إذا كان السمة غير صحيحة؟ يجب علينا إعادة نقطة التعلق إلى داخل السمة المحلية.
من المعروف أن Overlay الخاص بمكون DatePickerPro في مكتبة مكونات DevUI يستخدم Overlay of Angular CDK، وبعد جولة من التحليل، قمنا باستبداله بالحقن كما يلي:
1) أولاً، نرث OverlayContainer وننفذ ElementOverlayContainer الخاص بنا كما هو موضح. أقل.
الشكل 19 قم بتخصيص ElementOverlayContainer واستبدال منطق _createContainer
2) ثم قم بتوفير ElementOverlayContainer الجديد مباشرة على جانب مكون المعاينة، وقم بتوفير Overlay جديد حتى يتمكن Overlay الجديد من استخدام OverlayContainer الخاص بنا. في الأصل يتم توفير Overlay وOverlayContainer على الجذر، وهنا نحتاج إلى تغطية هذين الاثنين.
الشكل 20: استبدل OverlayContainer بـ ElementOverlayContainer مخصص وقم بتوفير Overlay جديد،
انتقل الآن لمعاينة موقع الويب، وسيتم ربط DOM الخاص بالطبقة المنبثقة بنجاح بعنصر معاينة المكون.
الشكل 21: تم إرفاق حاوية Overlay الخاصة بـ cdk بـ dom المحدد. وقد نجحت المعاينة الجزئية للموضوع.
ويوجد أيضًا OverlayContainerRef مخصص في مكتبة مكونات DevUI لبعض المكونات ومقاعد أدراج الصناديق المشروطة، والتي تحتاج أيضًا إلى الاستبدال وفقًا لذلك. أخيرًا، يمكن تحقيق الطبقات المنبثقة والطبقات المنبثقة الأخرى لدعم السمات المحلية بشكل مثالي.
ملخص نقاط المعرفة : يمكن لنمط التجريد الجيد أن يجعل الوحدات قابلة للاستبدال وتحقيق برمجة جانبية أنيقة.
مع الحالة الأخيرة، أود أن أتحدث عن نهج أقل رسمية لتسهيل فهم الجميع لطبيعة الموفر، فإن تكوين الموفر يعني بشكل أساسي السماح له بمساعدتك في إنشاء مثيل موجود أو تعيينه.
نحن نعلم أنه إذا تم استخدام cdkOverlay، إذا أردنا أن يتبع المربع المنبثق شريط التمرير ويتم تعليقه في الموضع الصحيح، فسنحتاج إلى إضافة تعليمات cdkScrollable إلى شريط التمرير.
ولا يزال نفس السيناريو كما في المثال السابق. يتم تحميل صفحتنا بأكملها من خلال التوجيه، من أجل البساطة، قمت بكتابة شريط التمرير على مضيف المكون.
الشكل 22: يكتب شريط تمرير تجاوز سعة المحتوى overflow:auto في المكون:host،
وبهذه الطريقة نواجه مشكلة أكثر صعوبة يتم تحديدها من خلال تعريف جهاز التوجيه، أي أنه <app-theme-picker-customize></app-theme-picker-customize>
، ثم كيفية إضافة تعليمات cdkScrollable؟ الحل هو كما يلي. بعض التعليمات البرمجية مخفية هنا ولم يتبق سوى الكود الأساسي.
الشكل 23 قم بإنشاء مثيل من خلال الحقن واستدعاء دورة الحياة يدويًا
هنا، يتم إنشاء مثيل cdkScrollable من خلال الحقن، ويتم استدعاء دورة الحياة بشكل متزامن خلال مرحلة دورة حياة المكون.
هذا الحل ليس طريقة شكلية، لكنه يحل المشكلة، وقد ترك هنا كفكرة واستكشاف لذوق القراء.
ملخص نقاط المعرفة : يمكن لموفر تكوين حقن التبعية إنشاء مثيلات، ولكن يرجى ملاحظة أنه سيتم التعامل مع المثيلات كفئات خدمة عادية ولا يمكن أن يكون لها دورة حياة كاملة.
يرجى الرجوع إلى منشور المدونة هذا: "عرض تطبيقات Angular في الوحدة الطرفية"
الشكل 24: استبدل عارض RendererFactory2 والمحتويات الأخرى للسماح بتشغيل Angular على الجهاز الطرفي.
استبدل المؤلف RendererFactory2 والعارضين الآخرين حتى يمكن تشغيل تطبيق Angular على الجهاز الطرفي. هذه هي مرونة التصميم الزاوي، حتى أنه يمكن استبدال النظام الأساسي. يمكن العثور على تفاصيل الاستبدال التفصيلية في المقالة الأصلية ولن يتم توسيعها هنا.
ملخص نقاط المعرفة : تكمن قوة حقن التبعية في أن الموفر يمكنه تكوينه بنفسه وتنفيذ منطق الاستبدال في النهاية.
قدمت هذه المقالة وضع حقن التبعية لانعكاس التحكم وفوائده، كما قدمت أيضًا كيف يبحث حقن التبعية في Angular عن التبعيات، وكيفية تكوين الموفرين، وكيفية استخدام الديكورات المحدودة والمرشحة للحصول على المثيل المطلوب، وكذلك من خلال N. تحلل الحالات كيفية الجمع بين نقاط المعرفة الخاصة بحقن التبعية لحل المشكلات التي تتم مواجهتها في التطوير والبرمجة.
من خلال فهم عملية البحث عن التبعيات بشكل صحيح، يمكننا تكوين الموفر في الموقع المحدد (الحالة 1 و2)، واستبدال المثيلات الأخرى بمثيلات فردية (الحالة 4 و5)، وحتى الاتصال عبر قيود حزم المكونات المتداخلة (الأمثلة المقدمة). الحالة 3) أو استخدم منحنى الطريقة المقدم لتنفيذ إنشاء مثيل للتعليمات (الحالة 6).
يبدو أن الحالة 5 هي بديل بسيط، ولكن القدرة على كتابة بنية تعليمات برمجية يمكن استبدالها تتطلب فهمًا متعمقًا لوضع الحقن وتجريدًا أفضل ومعقولًا لكل وظيفة، وإذا لم يكن التجريد مناسبًا، فستتم التبعيات لا يمكن استخدام أقصى تأثير للحقن. يوفر وضع الحقن مساحة أكبر ممكنة للوحدات لتكون قابلة للتوصيل، ومكونة من المكونات الإضافية، ومرتكزة على أجزاء، مما يقلل من الاقتران ويزيد من المرونة، بحيث يمكن للوحدات أن تعمل معًا بشكل أكثر أناقة وتناغمًا.
لا تستطيع وظيفة حقن التبعية القوية تحسين مسارات اتصال المكونات فحسب، بل الأهم من ذلك، يمكنها أيضًا تحقيق انعكاس التحكم، وتعريض المكونات المغلفة لمزيد من جوانب البرمجة، كما يمكن أن يصبح تنفيذ بعض المنطق الخاص بالأعمال أكثر مرونة.