عادةً عند استخدام التعليمات في NG ، فإن وظيفة الارتباط التي تستخدمها معظمها هي سمة الارتباط. سوف تخبرك المقالة التالية بالاستخدام والاختلافات بين الكذب ، والوصل المسبق ، وما بعد الوصلة.
تعتبر الإرشادات في AngularJs سحرية للغاية ، مما يتيح لك إنشاء مكونات دلالية وقابلة لإعادة الاستخدام للغاية ، والتي يمكن فهمها على أنها رائدة في مكونات الويب.
هناك بالفعل العديد من المقالات والكتب ذات الصلة على الإنترنت التي تقدم كيفية استخدام التعليمات. إذا قارنتها ، فنادراً ما تقدم الفرق بين التجميع والرابط ، ناهيك عن الرابط المسبق وما بعد الوصلة.
تقول معظم البرامج التعليمية ببساطة أنه سيتم استخدام التجميع داخل NG ، ويوصى به أن تستخدم فقط سمة الارتباط ، وهذا هو الحال في معظم الإرشادات.
هذا أمر مؤسف للغاية ، لأن فهم الفرق بين هذه الوظائف بشكل صحيح سيؤدي إلى تحسين فهمك لآلية التشغيل الداخلية لـ NG ويساعدك على تطوير تعليمات مخصصة أفضل.
لذا اتبعني لرؤية المحتوى التالي خطوة بخطوة لفهم ماهية هذه الوظائف ومتى يجب استخدامها
تفترض هذه المقالة أن لديك فهمًا معينًا للتعليمات. إذا لم يكن الأمر كذلك ، فمن المستحسن بشدة أن تقرأ هذا قسم دليل مطور AngularJS حول التوجيهات
كيفية معالجة التعليمات في NG
قبل البدء في التحليل ، دعونا نرى كيف يتعامل NG-Chinese مع التعليمات.
عندما يقوم المتصفح بإعداد صفحة ، فإنه يقرأ بشكل أساسي هوية HTML ، ثم يقوم بإنشاء عقدة DOM ، وتبث حدثًا لنا بعد إنشاء شجرة DOM.
عند استخدام علامات البرنامج النصي لتحميل رمز تطبيق NG في الصفحة ، يستمع NG إلى حدث إكمال DOM أعلاه ويجد عناصر ذات سمات NG-APP.
بعد العثور على هذا العنصر ، تبدأ NG في معالجة DOM مع نقطة انطلاق هذا العنصر ، لذلك إذا تمت إضافة NG-APP إلى عنصر HTML ، فسيبدأ NG في معالجة DOM مع عنصر HTML.
بدءًا من نقطة البداية هذه ، يبدأ NG في البحث عن جميع عناصر الأطفال بشكل متكرر ، والذي يتوافق مع قواعد التعليمات المحددة في التطبيق.
تعتمد كيفية التعامل مع تعليمات NG فعليًا على خصائص الكائن التي تحددها. يمكنك تحديد وظيفة ترجمة أو رابط ، أو استخدام وظائف ما قبل الوصلة وما بعد الوصلات بدلاً من الارتباط.
إذن ما الفرق بين هذه الوظائف؟ لماذا تستخدمه؟ ومتى؟
مع هذه الأسئلة ، اتبعني خطوة بخطوة للإجابة على هذه الألغاز
قطعة من الرمز
لشرح الاختلافات بين هذه الوظائف ، سأستخدم مثالًا بسيطًا وسهل الفهم أدناه
1. إذا كان لديك أي أسئلة ، فيرجى عدم التردد في إضافة تعليقاتك أدناه.
تحقق من رمز علامة HTML التالي
نسخة الكود كما يلي:
<stly-One>
<stele-اثنين>
<المستوى الثالث>
مرحبًا
</المستوى ثلاثة>
</المستوى الثاني>
</المستوى واحد>
ثم هناك قطعة من رمز JS
نسخة الكود كما يلي:
var app = Angular.module ('plunker' ، []) ؛
وظيفة تم إنشاؤها (الاسم) {
وظيفة الإرجاع () {
يعود {
تقييد: 'e' ،
ترجمة: وظيفة (Telem ، Tattrs) {
console.log (name + ': compile') ؛
يعود {
Pre: Function (Scope ، IElem ، IATTRS) {
console.log (name + ': pre link') ؛
} ،
Post: Function (Scope ، IElem ، IATTRS) {
console.log (name + ': post link') ؛
}
}
}
}
}
}
app.dircive ('LevelOne' ، CreatedIricive ('LevelOne')) ؛
app.directive ('LevelTwo' ، CreatedIrictive ('LevelTwo')) ؛
app.DIRECITION ('levelthree' ، تم إنشاؤها ('levelthree')) ؛
والنتيجة بسيطة للغاية: دع NG يتعامل مع ثلاث تعليمات متداخلة ، وكل تعليمات لها وظائفها الخاصة ، ودالة ما قبل الوصلات ، وما بعد الوصلات. ستقوم كل وظيفة بطباعة خط في وحدة التحكم لتحديد نفسه.
يسمح لنا هذا المثال بفهم العملية الداخلية لـ NG بإيجاز عند معالجة التعليمات
إخراج الكود
فيما يلي لقطة شاشة لنتيجة الإخراج على وحدة التحكم
إذا كنت ترغب في تجربة هذا المثال بنفسك ، فيرجى النقر فوق هذا PLNKR ثم عرض النتائج في وحدة التحكم.
رمز التحليل
أول شيء يجب ملاحظته هو ترتيب نداء هذه الوظائف:
نسخة الكود كما يلي:
// مرحلة التجميع
// LevelOne: تسمى وظيفة التجميع
// LevelTwo: تسمى وظيفة التجميع
// levelthree: يتم استدعاء وظيفة التجميع
// مرحلة ما قبل الوصلة
// LevelOne: تسمى وظيفة الرابط المسبق
// LevelTwo: تسمى وظيفة الرابط المسبق
// levelthree: تسمى وظيفة الرابط قبل
// مرحلة ما بعد الوصلات (لاحظ الترتيب العكسي)
// Levelthree: تسمى وظيفة الرابط بعد ذلك
// Leveltwo: تسمى وظيفة الرابط بعد ذلك
// LevelOne: تسمى وظيفة الرابط بعد ذلك
يوضح هذا المثال بوضوح أن NG يقوم بتجميع جميع الإرشادات قبل الارتباط ، ثم يتم تقسيم الارتباط إلى مراحل ما قبل الوصلة وما بعد الوصلة.
لاحظ أنه يتم تنفيذ ترتيب تنفيذ الترجمة والوصل المسبق بالتتابع ، لكن ما بعد الوصل هو عكس ذلك تمامًا.
لذا فإن ما سبق حدد بوضوح مراحل مختلفة ، ولكن ما هو الفرق بين الترجم والوصل المسبق؟ كلاهما في نفس ترتيب التنفيذ ، فلماذا يتعين علينا تقسيمهما إلى وظيفتين مختلفتين؟
دوم
من أجل الحفر بشكل أعمق ، دعنا ببساطة تعديل الكود أعلاه ، والذي سيطبع أيضًا متغيرات العناصر في قائمة المعلمات في كل وظيفة
نسخة الكود كما يلي:
var app = Angular.module ('plunker' ، []) ؛
وظيفة تم إنشاؤها (الاسم) {
وظيفة الإرجاع () {
يعود {
تقييد: 'e' ،
ترجمة: وظيفة (Telem ، Tattrs) {
console.log (name + ': compile =>' + telem.html ()) ؛
يعود {
Pre: Function (Scope ، IElem ، IATTRS) {
console.log (name + ': pre link =>' + ielem.html ()) ؛
} ،
Post: Function (Scope ، IElem ، IATTRS) {
console.log (name + ': post link =>' + ielem.html ()) ؛
}
}
}
}
}
}
app.dircive ('LevelOne' ، CreatedIricive ('LevelOne')) ؛
app.directive ('LevelTwo' ، CreatedIrictive ('LevelTwo')) ؛
app.DIRECITION ('levelthree' ، تم إنشاؤها ('levelthree')) ؛
انتبه إلى الإخراج في Console.log ، باستثناء إخراج علامة HTML الأصلية ، لا يوجد أي تغيير آخر.
هذا يجب أن يعمق فهمنا لسياق هذه الوظائف.
قم بتشغيل الكود مرة أخرى لترى
الإخراج
فيما يلي لقطة شاشة لنتيجة الإخراج على وحدة التحكم
إذا كنت لا تزال ترغب في تشغيله بنفسك لرؤية التأثير ، فيمكنك النقر فوق هذا PLNKR ثم عرض نتائج الإخراج في وحدة التحكم.
يراقب
يمكن أن يعرض إخراج نتيجة DOM بعض الأشياء المثيرة للاهتمام: محتوى DOM يختلف في تجميع وظيفتي وترجمة ما قبل الوصلة
إذن ماذا حدث؟
ترجمة
نحن نعلم بالفعل أنه عندما يجد NG أن بناء DOM قد اكتمل ، نبدأ في معالجة DOM.
لذلك عندما يعبر NG DOM ، يواجه عنصر المستوى الأول ويتعلم من تعريفه أن بعض الوظائف اللازمة يجب تنفيذها
نظرًا لأن وظيفة الترجمة محددة في كائن التعليمات لتعليمات المستوى الأول ، سيتم استدعاؤها وتمرير كائن عنصر كمعلمة له
إذا نظرت عن كثب ، فسترى أنه عندما يقوم المتصفح بإنشاء كائن العنصر هذا ، فإنه لا يزال العلامة HTML الأصلية.
1. في NG ، عادةً ما يتم استخدام DOM الأصلي لتحديد عنصر القالب ، لذلك استخدمت الاسم عن بعد عند تحديد معلمات دالة الترجم ، ويشير هذا المتغير إلى عنصر القالب.
بمجرد تشغيل وظيفة الترجمة في تعليمات المستوى ، فإن NG ستجتاز بشكل متكرر عقد DOM الخاصة بها في العمق ، ثم تكرار هذه العمليات على المستوى الثاني والمستوى.
بعد الوصل
قبل أن ندخل في وظيفة ما قبل الوصلات ، دعونا نلقي نظرة على وظيفة ما بعد الوصل.
2. إذا كنت تستخدم وظيفة ارتباط واحدة فقط عند تحديد التعليمات ، فسيتعامل NG هذه الوظيفة على أنها ما بعد الوصلات ، لذلك نحتاج إلى مناقشة هذه الوظيفة أولاً.
بعد أن اجتاز NG جميع DOMS وركض جميع وظائف التجميع ، يتم استدعاء وظيفة ما بعد الوصلات المرتبطة في الاتجاه المعاكس.
يبدأ DOM الآن في عكس وتنفيذ وظيفة ما بعد الوصلات. لذلك ، بدت هذه المكالمة العكسية غريبة بعض الشيء من قبل ، ولكن من المنطقي في الواقع القيام بذلك.
عند تشغيل تعليمات ما بعد الوصلات التي تحتوي على عمليات تعليمية فرعية ، يمكن لقاعدة ما بعد الوصلات العكسي أن يضمن تشغيل ما بعد الوصلات الفرعية.
لذلك ، عند تشغيل وظيفة ما بعد الوصلات لتعليمات المستوى الأول ، يمكننا التأكد من أن ما بعد الارتباط بين المستوى الثاني والمستوى الثالث قد تم تشغيله بالفعل.
لهذا السبب يعتقد الناس أن ما بعد الوصل هو المكان الأكثر أمانًا أو الافتراضي لكتابة منطق العمل.
ولكن لماذا يختلف العنصر هنا عن العنصر في الترجمة؟
بمجرد استدعاء NG وظيفة ترجمة التعليمات ، سيتم إنشاء كائن مثيل عنصر لعنصر القالب ويتم توفير كائن النطاق له. قد يكون هذا النطاق مثيلًا جديدًا ، أو قد يكون موجودًا بالفعل ، قد يكون نطاقًا فرعيًا ، أو قد يكون نطاقًا مستقلًا. كل هذه تعتمد على قيمة سمة النطاق في كائن تعريف التعليمات.
لذلك عند حدوث الارتباط ، يكون عنصر المثيل وكائن النطاق هذا متاحًا بالفعل ، ويتم تمريره كمعلمات بواسطة NG إلى قائمة المعلمات لوظيفة ما بعد الوصلات.
1. أنا شخصياً أستخدم اسم IELEM دائمًا لتحديد معلمة وظيفة الارتباط ، ويشير إلى مثيل العنصر
لذلك ، فإن كائن معلمة العنصر في دالة ما بعد الوصلات (ما قبل الوصل) هو مثيل عنصر بدلاً من عنصر قالب.
لذا فإن الإخراج في المثال أعلاه مختلف
قبل الوصل
عند كتابة وظيفة ما بعد الوصلات ، يمكنك التأكد من أنه عند تنفيذ وظيفة ما بعد الوصلات ، تم تنفيذ وظائف ما بعد الوصلة لجميع تعليمات الأطفال.
في معظم الحالات ، يمكن أن يكون أفضل ، لذلك عادة ما نستخدمه لكتابة رمز التعليمات.
ومع ذلك ، فإن NG يوفر لنا آلية ربط إضافية ، أي وظيفة ما قبل الوصلات ، والتي يمكن أن تضمن تشغيل بعض التعليمات البرمجية الأخرى قبل تنفيذ وظيفة ما بعد الوصلات لجميع عمليات الترشيح الفرعية.
هذه الجملة تستحق الاعتبار المتكرر
يمكن أن تضمن وظيفة ما قبل الوصلات تنفيذها على مثيل العنصر وقبل تشغيل ما بعد الوصلات من عمليات الترشيح الفرعية.
لذلك من المنطقي عكس وظيفة ما بعد الوصلات ، فإنه ينفذ وظيفة ما قبل الوصل بالترتيب الأصلي.
هذا يعني أيضًا أن وظيفة ما قبل الوصلات تعمل قبل وظيفة ما قبل الوصلة لجميع عمليات الاستثناع الفرعية ، وبالتالي السبب الكامل هو:
يمكن ضمان تنفيذ وظيفة ما قبل الوصلات للعنصر قبل تشغيل ما بعد الوصلات وترابط ما قبل الارتباط لجميع عمليات الترشيح الفرعية. انظر الشكل أدناه:
مراجعة
إذا نظرنا إلى الوراء إلى الإخراج الأصلي أعلاه ، يمكننا أن ندرك بوضوح ما يجري:
نسخة الكود كما يلي:
// هنا لا تزال العناصر هي عناصر القالب الأصلية
// مرحلة التجميع
// LevelOne: تم استدعاء وظيفة التجميع على DOM الأصلي
// LevelTwo: تم استدعاء وظيفة التجميع على DOM الأصلي
// Levelthree: تم استدعاء وظيفة التجميع على DOM الأصلي
// اعتبارًا من هنا ، تم إنشاء مثيل للعناصر و
// مرتبطة بالنطاق
// (على سبيل المثال ، سيكون للتكرار حالات متعددة)
// مرحلة ما قبل الوصلة
// LevelOne: تم استدعاء وظيفة الرابط المسبق على مثيل العنصر
// LevelTwo: تم استدعاء وظيفة الرابط المسبق على مثيل العنصر
// Levelthree: تم استدعاء وظيفة الرابط المسبق على مثيل العنصر
// مرحلة ما بعد الوصلات (لاحظ الترتيب العكسي)
// Levelthree: تتم استدعاء وظيفة الرابط بعد ذلك على مثيل العنصر
// LevelTwo: وظيفة الرابط المنشور تسمى مثيل العنصر
// LevelOne: تتم استدعاء وظيفة الرابط المنشور على مثيل العنصر
ملخص
إذا نظرنا إلى الوراء في التحليل أعلاه ، يمكننا وصف الاختلافات واستخدام هذه الوظائف:
وظيفة التجميع
استخدم وظيفة التجميع لتغيير DOM (عنصر القالب) الأصلي ، قبل أن ينشئ NG مثيل DOM الأصلي ومثيل النطاق.
يمكن تطبيقه على المواقف التي يجب إنشاء مثيلات عناصر متعددة وهناك عنصر قالب واحد فقط. NG-Repeat هو أفضل مثال. يقوم بتغيير DOM الأصلي في مرحلة وظيفة الترجم لإنشاء عقد DOM أصلية متعددة ، ثم يقوم كل منها بإنشاء مثيلات عناصر. نظرًا لأن الترجمة سيتم تشغيلها مرة واحدة فقط ، فقد يحسن الأداء عندما تحتاج إلى إنشاء مثيلات عناصر متعددة.
يتم تمرير عنصر القالب والسمات ذات الصلة كمعلمات لوظيفة الترجمة ، ولكن لا يمكن استخدام النطاق في هذا الوقت:
ها هي الوظيفة تبدو:
نسخة الكود كما يلي:
/**
* ترجمة وظيفة
*
* param telem - عنصر القالب
* param tattrs - سمات عنصر القالب
*/
وظيفة (Telem ، tattrs) {
// ...
} ؛
وظيفة ما قبل الوصلة
استخدم وظيفة ما قبل الوصلات لتشغيل بعض رمز العمل بعد تنفيذ NG وظيفة الترجم ، ولكن قبل أن يتم تنفيذ وظيفة ما بعد الوصلات لجميع عمليات التعيين الفرعية.
سيتم تمرير كائن النطاق ومثيل العنصر كمعلمات إلى وظيفة ما قبل الوصلة:
ها هي الوظيفة تبدو:
نسخة الكود كما يلي:
/**
* وظيفة ما قبل الوصلة
*
* scope param - النطاق المرتبط بهذا
* param ielem - عنصر مثيل
* param iattrs - سمات عنصر المثيل
*/
الوظيفة (النطاق ، ielem ، iattrs) {
// ...
} ؛
وظيفة ما بعد الوصل
استخدم وظيفة ما بعد الوصل لتنفيذ منطق العمل. في هذه المرحلة ، تعرف بالفعل أنه تم تجميع جميع عمليات الاستثناع الفرعية وأن وظائف ما قبل الوصلات وما بعد الوصلات قد تم تنفيذها.
هذا هو ما يعتبر رمز المنطق أعمال الكتابة الأكثر أمانًا والأمانة.
يتم تمرير مثيل النطاق ومثيل العنصر كمعلمات إلى وظيفة ما بعد الوصلة:
ها هي الوظيفة تبدو:
نسخة الكود كما يلي:
/**
* وظيفة ما بعد الوصلة
*
* scope param - النطاق المرتبط بهذا
* param ielem - عنصر مثيل
* param iattrs - سمات عنصر المثيل
*/
الوظيفة (النطاق ، ielem ، iattrs) {
// ...
} ؛
لخص
الآن يجب أن يكون لديك فهم واضح للاختلافات بين التجميع ، وسبق الوصل ، وبعد الوصل ، وهذه الوظيفة.
إذا لم تكن قد لم تكن كذلك ، وكنت مطور NG جادًا ، فإنني أوصي بشدة بقراءة هذه المقالة مرة أخرى حتى تفهمها
يعد فهم هذه المفاهيم أمرًا مهمًا للغاية ، والذي يمكن أن يساعدك على فهم كيفية عمل التعليمات الأصلية NG ، ويمكن أن يساعدك أيضًا في تحسين التعليمات المخصصة الخاصة بك.
إذا كان لديك أي أسئلة ، يرجى إضافة أسئلتك في التعليقات أدناه
في المستقبل ، سنستمر في تحليل سؤالين آخرين حول التعليمات:
1. كيف يعمل التوجيهات التي تستخدم سمات النقل؟
2. كيف ترتبط وظيفة وحدة التحكم في التعليمات؟
أخيرًا ، إذا وجدت شيئًا خاطئًا في هذا المقال ، فيرجى التعليق علي في الوقت المناسب
شكرًا!