التوجيه هو وسيلة لتعليم HTML للعب بعض الحيل الجديدة. أثناء تجميع DOM ، تطابق التوجيهات HTML وتنفيذ. هذا يسمح بسلوك التسجيل التوجيهي أو تحويل هياكل DOM.
يأتي Angular مع مجموعة من التوجيهات المدمجة ، وهو أمر مفيد للغاية لبناء تطبيق ويب. إذا واصلت التوسع ، يمكنك تحديد لغة محددة للمجال (DSL) في HTML.
1. اقتباس التوجيهات في HTML
التوجيه لديه تسمية على غرار الجمل ، مثل ngbind (يبدو أنه غير قابل للاستخدام في الخصائص ~). ومع ذلك ، يمكن أيضًا تسمية التوجيه بنوع أسفل الثعابين (حالة ثعبان) ، والتي يجب توصيلها من خلال: (القولون) ، - (ناقص) أو _ (تحت السطح). كخيار اختياري ، يمكن توجيه التوجيه مع "X-" أو "Data-" لتلبية احتياجات التحقق من HTML. فيما يلي الأسماء القانونية للتوجيهات:
يمكن وضع التوجيه بأسماء العناصر والسمات والفصول والتعليقات. فيما يلي الطريقة المكافئة للاقتباس Mydir ، التوجيه. (لكن العديد من التوجيهات تقتصر على استخدام "الخصائص")
<span my-dir = "exp"> </span> <span> </span> <my-dir> </my-dir> <!-التوجيه: my-dir exp->
يمكن ذكر التوجيه بعدة طرق ، والقوائم التالية طرق مكافئة:
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> invoke-doke-dokevicive </title> <style type = "text/css"> .ng-cloak {display: none ؛ } </style> </head> <body> <div ng-controller = "myctrl"> hello <input ng-model = "name"/> <hr/> ngbind = "name" ng_bind = "name" <span ng_bind = "name"> </span> <br/> ng-bind = "name" <span ng-bind = "name"> </span> <brate-ng-bind = "name" <span data-bind = "name"> <br/> x-ng-bind = "name"> </span> <br/> </div> <script src = "../ Angular 1.0.1.js" type = "text/javaScript"> </script> <script type = "text/javaScript"> myctrl ($ scope) {$ scope.name = } </script> </body> </html>2. سلسلة الاستيفاء
أثناء عملية التجميع ، يطابق برنامج التحويل البرمجي النص مع تعبيرات مضمنة في السمات (مثل {{something}}) من خلال خدمة interpolate $. سيتم تسجيل هذه التعبيرات كساعات وسيتم تحديثها معًا كجزء من دورة Digest (ألم تكن حلقة الهضم من قبل؟!). هنا استيفاء بسيط:
<img src = "img/{{username}}. jpg"/> hello {{username}}!
3. عملية التجميع ، ومطابقة التوجيه
ثلاث خطوات لـ "تجميع" HTML:
1. أولاً ، قم بتحويل HTML إلى كائنات DOM من خلال واجهة برمجة تطبيقات المتصفح القياسية. هذه خطوة مهمة للغاية. لأن القالب يجب أن يكون قابلاً للتطبيق (متوافق مع المواصفات). يمكن مقارنة ذلك مع معظم أنظمة القالب ، والتي تعتمد بشكل عام على سلاسل ، وليس عناصر DOM.
2. يتم تجميع DOM عن طريق استدعاء طريقة $ comple (). تعبر هذه الطريقة DOM وتتطابق مع التوجيه. إذا نجحت المباراة ، فسيتم إضافتها إلى قائمة التوجيه مع DOM المقابلة. طالما تم تحديد جميع التوجيهات المرتبطة بـ DOM المحددة ، سيتم فرزها في الأولوية وتنفيذ وظيفة الترجم () بهذا الترتيب. تتمتع وظيفة التوجيه التوجيهية بفرصة لتعديل بنية DOM وهي مسؤولة عن توليد وظيفة LINK (). تقوم طريقة $ compile () بإرجاع وظيفة الارتباط المشتركة ، وهي مجموعة من الوظائف المرتبطة التي يتم إرجاعها بواسطة وظيفة ترجمة التوجيه نفسه.
3. قم بتوصيل القالب بالنطاق من خلال وظيفة الارتباط التي تم إرجاعها في الخطوة السابقة. وهذا بدوره يستدعي وظيفة الارتباط الخاصة التوجيهية ، مما يسمح لهم بتسجيل بعض المستمعين على العنصر ، وإنشاء بعض الساعات ذات النطاق. والنتيجة في هذا هو الارتباط في اتجاهين ، فوري بين النطاق و DOM. عندما يتغير النطاق ، سيحصل DOM على الاستجابة المقابلة.
var $ compile = ... ؛ // حقن في الكود الخاص بك var scope = ... ؛ var html = '<div ng-bind =' exp '> </viv>' ؛ // الخطوة 1: تحليل HTML في قالب DOM element var = Angular.Element (HTML) ؛ // الخطوة 2: ترجمة القالب var linkfn = $ compile (template) ؛ // الخطوة 3: ربط القالب المترجم بالنطاق. Linkfn (النطاق) ؛
4. أسباب وراء فصل الترجم/الارتباط
في هذا الوقت ، قد تتساءل عن سبب تقسيم عملية التجميع إلى خطوتين: ترجمة ورابط. لفهم هذا ، دعونا نلقي نظرة على مثال حقيقي (مكرر)
مرحبًا {{user}} ، لديك هذه الإجراءات: <ul> <li ng-repeat = "Action in user.actions"> {action.description}} </li> </ul>ببساطة ، السبب في أننا نفصل خطوتين للترجمة والرابط هو أنه في بعض الأحيان يجب تغيير بنية DOM المقابلة بعد تغيير النموذج ، مثل Repital.
عندما يتم تجميع المثال أعلاه ، سيتكرر المترجم من خلال جميع العقد للعثور على التوجيه. {{user}} هو مثال على توجيه الاستيفاء. ngrepeat هو توجيه آخر. لكن ngrepeat لديه صعوبة. يتطلب القدرة على إنشاء LI الجديدة بسرعة لكل إجراء في المستخدمين. هذا يعني أنه من أجل تلبية الغرض من استنساخ LI وتضمين إجراءات محددة (هنا يشير إلى إحدى قيم إجراءات المستخدم) ، فإنه يحتاج إلى الحفاظ على نسخة نظيفة من عنصر LI ، والتي يجب استنساخها وإدراجها في عنصر UL. لكن استنساخ عنصر LI ليس كافيًا. يجب أيضًا تجميع LI بحيث يمكن تحليل توجيهه ({action.descriptions}}) في النطاق الصحيح. تقوم الطريقة الأصلية عمومًا ببساطة بإدراج نسخة من عنصر LI ثم تجمعها. ومع ذلك ، فإن تجميع نسخ من كل عنصر LI سيكون أبطأ ، لأن عملية التجميع تتطلب منا اجتياز شجرة عقدة DOM ، والعثور على التوجيهات وتشغيلها. إذا كان لدينا ترجمة تحتاج إلى معالجة 100 عنصر من خلال مكرر ، فسنكون عالقين في مشكلات الأداء.
حل المشكلة هو تحطيم عملية التجميع إلى خطوتين. تتعرف مرحلة التجميع على جميع التوجيهات وفرزها حسب الأولوية ، مما يربط نطاقًا محددًا مع LI محددة أثناء مرحلة الارتباط.
يجمع Ngrepeat LIS الفردي بشكل منفصل لمنع عملية التجميع من الوقوع في عناصر LI. نتيجة التجميع لعنصر LI هي دالة ربط توجيهية تحتوي على جميع التوجيهات الواردة في عنصر LI ، جاهزة للتواصل مع نسخة عنصر LI المحدد. في وقت التشغيل ، يراقب Ngrepeat التعبير ويتم إضافته كعنصر إلى مجموعة من نسخ عناصر LI ، مما يخلق نطاقًا جديدًا لعناصر LI المستنسخة ، واستدعاء وظيفة الارتباط المقابلة للنسخة.
تلخيص:
1. وظيفة التجميع - تعتبر وظائف التجميع نادرة نسبيًا في التوجيهات ، لأن معظم التوجيهات تهتم فقط بالعمل مع عناصر DOM المحددة ، بدلاً من تغيير قوالب عناصر DOM (DOM نفسها وهيكلها الداخلي). لتحسين الأداء ، يمكن نقل بعض العمليات التي يمكن مشاركتها بواسطة مثيلات توجيهية إلى وظيفة التجميع.
2. وظيفة الارتباط - عدد قليل جدًا من التوجيهات ليس لها وظيفة ارتباط. تسمح وظيفة الارتباط التوجيهية بتسجيل مستمع على النسخة المحددة من مثيل عنصر DOM ، أو نسخ محتوى معين من النطاق إلى DOM.
5. اكتب توجيهًا (نسخة بسيطة)
في هذا المثال ، سنقوم بإنشاء توجيه يعرض الوقت الحالي وفقًا لتنسيق الإدخال.
<! doctype html> <html lang = "zh-cn" ng-app = "timeformat"> <head> <meta charset = "utf-8"> <title> time-format </title> </head> <body> <div ng-controller = "myctrl" id = "main" format: type = "text"/> <hr/> <!-السمة التالية x-current-time هي تجربة التسمية القانونية المذكورة أعلاه ~~ الحالي: الوقت ، الوقت الحالي ، الوقت الحالي ، الوقت الحالي للبيانات -_- !!! -> الوقت الحالي هو: <span x-current-time = "format" id = "myformat"> </span> <br/> <button ng-click = "remove () type = "text/javaScript"> Angular.module ("timeFormat" ، []) وظيفة الترجمة ، لماذا؟) وظيفة الإرجاع (النطاق ، العنصر) {var intervalid ؛ Scope. watch (attr.currenttime ، function (value) {scope.format = updateTime () ؛}) ؛ }) يمكن أن يكون الحدث $ تدمير!6. اكتب توجيهًا (نسخة مفصلة)
فيما يلي إنشاء عينة لتوجيه (قالب تعريف الكائن التوجيهية). إذا كنت ترغب في رؤية القائمة التفصيلية ، فيرجى متابعة القراءة.
var mymodule = Angular.Module (...) ؛ mymodule.directive ('Direcivename' ، Function Factory (enjectables) {var direciedefinitionObject = {priority: 0 ، template: '<viv> </viv>' ، templateUrl: 'Directive.html' ، applain: false ، transclude: false ، "a '، scope: fult: fumpile (talment ، Pre: Prelink (Scope ، IELEMENT ، IATTRS ، Controller) {...في معظم السيناريوهات ، لا نحتاج إلى تحكم دقيق ، لذلك يمكن تبسيط التعريف أعلاه. سيتم تفسير تحديد كل جزء من القالب في الفصل التالي. في هذا الفصل ، نركز فقط على أيزومرات هذا الهيكل العظمي الذي يحدد القالب (أيزومرات هذا الهيكل العظمي ، لا أفهم ... أتطلع إلى إضافة الجميع).
الخطوة الأولى في تبسيط الكود الخاص بك هي الاعتماد على القيم الافتراضية. لذلك ، يمكن تبسيط الكود أعلاه إلى:
var mymodule = Angular.Module (...) ؛ mymodule.directive ('DIREVIVERAME' ، Function Factory (enjectables) {var direciedefinitionObject = {compile: function compile (telement ، tattrs) {return function postlink (scope ، iElement ، IATTRS) {...}} ؛تهتم معظم التوجيهات فقط بالحالات ، وليس تحويل القالب ، بحيث يمكن تبسيطها بشكل أكبر (ترجمت بشدة ... نتطلع إلى إضافة الجميع):
var mymodule = Angular.Module (...) ؛ mymodule.directive ('DIREVIVERAME' ، Function Factory (enjectables) {return postlink postlink (scope ، iElement ، IATTRS) {...}}) ؛7. طريقة المصنع
طريقة المصنع مسؤولة عن إنشاء التوجيهات. يتم استخدامه مرة واحدة فقط ، فقط عندما يتطابق المترجم لأول مرة. يمكنك القيام ببعض عمليات التهيئة هنا. يتم تنفيذ طريقة المصنع من خلال $ enjector.invoke ، مما يسمح لها بالامتثال لجميع قواعد إعلان الحقن (قواعد شرح الحقن) ، مما يجعلها قابلة للحقن.
8. وصف كائن تعريف التوجيه
توفر كائنات التعريف التوجيهية بنية التحويل البرمجي. الخصائص هي كما يلي:
1.NAME - اسم النطاق الحالي. يمكن استخدام القيمة الافتراضية عند التسجيل (لا يتم ملؤها).
2. الإعلان- عندما يكون هناك توجيهات متعددة محددة في نفس عنصر DOM ، يكون من الضروري في بعض الأحيان توضيح أمر التنفيذ الخاص بهم. يتم استخدام هذه الخاصية لفرز قبل استدعاء وظيفة التوجيه. إذا كانت الأولوية هي نفسها ، فإن أمر التنفيذ غير مؤكد (بعد التجارب الأولية ، يتم تنفيذ أولئك الذين لديهم أولوية أعلى أولاً ، ونفس المستوى مشابه لـ "التنفيذ" بعد المرتبطة أولاً ".
3. الطرفية (المجموعة الأخيرة) - إذا تم ضبطها على "صحيح" ، فهذا يعني أن الأولوية الحالية ستصبح توجيهًا للمجموعة الأخيرة من التنفيذ. إذا كان أي توجيه هو نفسه الأولوية الحالية ، فسيظل يتم تنفيذه ، لكن الأمر غير مؤكد (على الرغم من أن الأمر غير مؤكد ، فإنه هو نفس ترتيب الأولوية. بعد تنفيذ الأولوية الحالية ، لن يتم تنفيذ أولوية أقل مرة أخرى).
4.Scope - إذا تم ضبطه على:
1) .True - سيتم إنشاء نطاق جديد لهذا التوجيه. إذا كانت هناك توجيهات متعددة في نفس العنصر الذي يتطلب نطاقًا جديدًا ، فسيظل ذلك يخلق نطاقًا واحدًا فقط. لا تنطبق قواعد النطاق الجديدة على قالب الجذر ، وبالتالي يميل قالب الجذر إلى الحصول على نطاق جديد.
2). {} (تجزئة الكائن) - سيتم إنشاء نطاق جديد للعزل. الفرق بين نطاق "العزل" والنطاق العام هو أنه لم يتم موروثه من نطاق الوالدين من خلال النماذج الأولية. يعد هذا مفيدًا للغاية لإنشاء مكونات قابلة لإعادة الاستخدام ويمكن أن يمنع القراءة أو تعديل البيانات بشكل فعال من نطاق الوالد. ينشئ هذا النطاق المستقل تجزئة كائن مع مجموعة من خصائص النطاق المحلي المستمدة من نطاق الوالد. هذه الخصائص المحلية مفيدة لقيم الاسم المستعارة للقوالب -_-!. تعريف السكان المحليين هو تجزئة من خاصية النطاق المحلي لمصدرها#&) $ &@#) ($ &#_):
3). @ أو ATTR - إنشاء خاصية SCOPE المحلية إلى خاصية DOM. لأن قيمة الخاصية هي دائمًا نوع السلسلة ، فإن هذه القيمة تُرجع دائمًا سلسلة. إذا لم يتم تحديد اسم السمة عبر ATTR ، فسيكون الاسم المحلي دائمًا باسم سمة DOM. على سبيل المثال ، <widget my-attr = "hello {{name}}"> ، يتم تعريف نطاق القطعة على النحو التالي: {localname: '@myattr'}. بعد ذلك ، سيقوم الاسم المحلي لخاصية نطاق القطعة بتخطيط القيمة الحقيقية التي تم تحويلها بواسطة "Hello {{name}}". بعد تغيير قيمة سمة الاسم ، ستتغير سمة الاسم المحلي لنطاق القطعة وفقًا لذلك (في اتجاه واحد فقط ، تختلف عن "=" أدناه). تتم قراءة سمة الاسم في نطاق الوالدين (وليس نطاق المكون)
4). = أو = التعبير (ربما attr هنا) - تعيين ربط ثنائي الاتجاه بين سمة النطاق المحلي وسمة نطاق الوالدين. إذا لم يتم تحديد اسم ATTR ، فسيكون الاسم المحلي متسقًا مع اسم السمة. على سبيل المثال ، <widget my-attr = "parentModel"> ، فإن النطاق المحدد بواسطة القطعة هو: {localModel: '= myattr'} ، ثم ستعمل خاصية نطاق القطعة "LocalName" على نطاق الوالد "ParentModel". في حالة حدوث أي تغييرات في ParentModel ، سيتغير موديل LocalModel أيضًا ، والعكس صحيح. (ربط ثنائي الاتجاه)
5). إذا لم يتم تحديد اسم ATTR ، فسيكون الاسم المحلي متسقًا مع اسم السمة. على سبيل المثال ، <widget my-attr = "count = count + value"> ، يتم تعريف نطاق القطعة على النحو التالي: {localfn: 'styrrement ()'} ، ثم يعزل خاصية النطاق "localfn" إلى وظيفة ملفوفة بتعبير الزيادة (). بشكل عام ، نريد تمرير البيانات من نطاق العزل إلى نطاق الوالدين من خلال التعبير. يمكن القيام بذلك عن طريق تمرير خريطة لقيمة المفتاح للمتغير المحلي في دالة التفاف للتعبير. على سبيل المثال ، إذا كان التعبير هو الزيادة (المبلغ) ، فيمكننا الاتصال بـ LocalFN من خلال LocalFn ({المبلغ: 22}) لتحديد قيمة المبلغ (المثال أعلاه لا يفهم حقًا ، وأين ذهبت؟).
5.controller - مُنشئ تحكم. سيتم تهيئة وحدة التحكم قبل خطوة الربط المسبق وتسمح للتوجيهات الأخرى بالمشاركة عبر الاسم المحدد (انظر الخاصية المتطلبات أدناه). هذا سيسمح للتوجيهات بالتواصل مع بعضها البعض وتعزيز السلوك المتبادل. تقوم وحدة التحكم بحقن الكائنات المحلية التالية بشكل افتراضي:
1). نطاق $ - نطاق مع العنصر الحالي
2). عنصر $ - العنصر الحالي
3). $ attrs - كائن السمة للعنصر الحالي
4). $ transclude - وظيفة ربط transpose مسبقة مسبقًا إلى نطاق التحويل الحالي: الوظيفة (cloneLinkingFN). (وظيفة ربط Transclude مسبقًا مسبقًا بنطاق الترجمة الصحيح)
6.Require - اطلب وحدة تحكم أخرى لتمريرها إلى وظيفة ربط التوجيه الحالية. يطلب تمرير اسم وحدة التحكم المباشرة. إذا كان لا يمكن العثور على وحدة التحكم المقابلة لهذا الاسم ، فسيتم طرح خطأ. يمكن أن يكون الاسم ما يلي ما يلي:
1).؟ - لا ترمي الاستثناءات. هذا يجعل هذا التبعية خيارًا.
2).^ - وحدة تحكم تسمح بالبحث عن عناصر الأصل
7. Restrict - سلسلة من مجموعة فرعية من EACM ، والتي تحد من التوجيه إلى طريقة الإعلان المحددة. إذا تم حذفه ، فإن التوجيه سيسمح فقط بإعلانات عبر السمات:
1) e-اسم العنصر: <my-directive> </ my-directive>
2) .A - اسم السمة: <div my -directive = "exp"> </div>
3). C - اسم الفصل: <div class = "my -directive: exp ؛"> </div>
4) .m-التعليق: <!-التوجيه: exp-directive->
8.Template - إذا كان استبداله صحيحًا ، استبدل محتوى القالب بعنصر HTML الحالي ، وقم بترحيل خصائص وفئة العنصر الأصلي معًا ؛ إذا كان خطأ ، يتم التعامل مع عنصر القالب كعنصر طفل للعنصر الحالي. لمزيد من المعلومات ، يرجى مراجعة الفصل "إنشاء واجهة مستخدم" (حيث ... إنشاء المكونات متوفرة ...)
9.TemplateUrl - هو في الأساس نفس القالب ، ولكن يتم تحميل القالب من خلال عنوان URL المحدد. نظرًا لأن تحميل القالب غير متزامن ، سيتم إيقاف الترجمة والربط وسيتم تنفيذها بعد التحميل.
10. الاسترداد - إذا تم ضبطه على TRUE ، فسوف يحل القالب محل العنصر الحالي بدلاً من إضافته إلى العنصر الحالي كعنصر طفل. (ملاحظة: عندما يكون صحيحًا ، يجب أن يكون للقالب عقدة جذر)
11.TransClude - تجميع محتوى عنصر ما بحيث يمكن استخدامه بواسطة التوجيه. مطلوب (في القالب) لاستخدامه (المشار إليه). تتمثل ميزة النقل في أن وظيفة ربط وظيفة يمكن أن تحصل على وظيفة ترجمة تكون مسبقة النطاق الحالي. بشكل عام ، قم بإنشاء عنصر واجهة مستخدم وإنشاء نطاق عزل. الترجمة ليست طفلًا ، بل شقيق نطاق العزلة. هذا سيجعل العنطيبة لها حالة خاصة وسيتم ربط عملية نقل النطاق الوالد (قبل القذارة). (لا أفهم الفقرة أعلاه. ولكن في التجارب الفعلية ، إذا تم استدعاء myDirective من خلال <any-directive> {{name}} </one my-directive> ويتم ضبط transclud سيكون هناك امتداد إضافي في بعض الأحيان.
1) .True - تحويل محتوى هذا التوجيه. (بهذا المعنى ، هو تجميع المحتوى مباشرة ونقله إلى المكان المحدد)
2). "العنصر" - يحول العنصر بأكمله ، بما في ذلك التوجيهات الأخرى ذات الأولوية المنخفضة. (على سبيل المثال ، بعد تجميع المحتوى بأكمله ، يتم التعامل معه ككل (ملفوف P في الخارج) وإدراجه في المكان المحدد)
12.compile - هنا هي وظيفة التجميع ، والتي سيتم شرحها بالتفصيل في الفصول التالية
13.Link - هنا هي وظيفة الارتباط ، والتي سيتم شرحها بالتفصيل في الفصل التالي. يتم استخدام هذه الخاصية فقط إذا لم يتم تعريف خاصية التجميع.
9. وظيفة التجميع
تجميع الوظيفة (Telement ، tattrs ، transclude) {...}
يتم استخدام وظيفة الترجمة للتعامل مع تحويل قوالب DOM. نظرًا لأن معظم التوجيهات لا تتطلب قوالب تحويل ، فلن يتم استخدام الترجم بشكل متكرر. التوجيه الذي يتطلب وظيفة التجميع ، بشكل عام تلك التي تحتاج إلى تحويل قوالب DOM (مثل nGrepeat) ، أو تلك التي تحتاج إلى تحميل المحتوى بشكل غير متزامن (مثل NGVIEW). دالة التجميع لها المعلمات التالية:
1.Telement - يستخدم عنصر القالب عنصر التوجيه الحالي. من الآمن إجراء تحويل القالب تحت العنصر الحالي أو عنصر الطفل الحالي.
2.Tattrs - سمات القالب - يمكن مشاركة سمات موحدة ، معلنة في العنصر الحالي ، بين التوجيهات المختلفة. لمزيد من التفاصيل ، يرجى الاطلاع على فصل السمات
3.Transclude دالة ربط للتحويل: وظيفة (النطاق ، clonelebink).
ملاحظة: إذا تم استنساخ القالب ، فلن يكون مثيل القالب ومثيل الارتباط هو نفس الكائن. للقيام بذلك ، ليس من الآمن فعل أي شيء آخر غير تحويل DOM في وظيفة التجميع ، والتي سيتم تطبيقها على جميع الحيوانات المستنسخة. على وجه الخصوص ، يجب تنفيذ عملية تسجيل مستمع حدث DOM في وظيفة الارتباط ، وليس وظيفة التجميع.
يمكن أن يكون لدالة التجميع قيمة إرجاع ، ويمكن أن يكون النوع وظيفة أو كائن.
1. عادة ما يتم استخدام وظيفة الإرجاع عندما لا تكون وظيفة التجميع مطلوبة (فارغة) ، والتي تعادل تسجيل وظيفة الارتباط من خلال الارتباط (تحدد مباشرة سمات القالب).
2. إرجاع كائن يحتوي على خصائص ما قبل وبعد ما يتيح لنا - يتيح لنا التحكم عند استدعاء وظيفة الارتباط أثناء مرحلة الارتباط. للحصول على التفاصيل ، يرجى الاطلاع على الفصول التالية حول وظائف الربط وما بعد الربط.
10. ربط الوظيفة
رابط الوظيفة (النطاق ، ielement ، IATTRS ، وحدة التحكم) {...}
وظيفة الارتباط هي المسؤولة عن تسجيل مستمع حدث DOM ، ويمكنها أيضًا إجراء عمليات تحديث DOM. سيتم تنفيذ وظيفة الارتباط بعد اكتمال عملية استنساخ القالب. يتم تخزين معظم منطق التوجيه هنا.
1.SCOPE - SCOPE - يتم استخدامه لتسجيل الساعات (http://docs.angularjs.org/api/ng.drootscope.scope#randwatch).
2.eelement - مثيل العنصر - عنصر يستخدمه التوجيه. من الآمن العمل على عناصر الأطفال في وظيفة postlink. لأن عناصر الطفل قد تم ربطها (متصلة بالنموذج؟!).
3.IATTRS - مثيل السمة - قائمة السمات للعنصر الحالي القياسي. مشترك بين جميع وظائف ربط التوجيه.
4.Controller - مثيل وحدة التحكم - إذا تم تعريف أحد وحدات التحكم في توجيه العنصر الحالي ، فيمكنك الحصول على مثيل وحدة التحكم هنا. تتم مشاركة وحدة التحكم هذه بين جميع التوجيهات ، مما يسمح لكل توجيه بمعالجة وحدة التحكم كقناة اتصال بينهما.
وظيفة ما قبل الوصلة
تنفيذ قبل ربط عنصر الطفل. ليس من الآمن القيام بتحويل DOM هنا ، لأن وظيفة ربط المترجم قد لا تحدد موقع العناصر الصحيحة عند الارتباط.
وظيفة ما بعد الوصل
تنفيذ بعد ربط عنصر الطفل. من الآمن أداء تحويل DOM هنا.
11. سمات
كائن السمة - كوسائط في Link () أو compile () - هو وسيلة للوصول إلى ما يلي:
1.
2. التواصل بين التوجيهات: تشترك جميع التوجيهات في مثيل كائن السمة ، بحيث يمكن للتوجيهات التواصل بين التوجيهات من خلال كائنات السمات.
3. الدعم الاستيفاء: يتم تعيين سمة الاستيفاء لكائن سمة ، مما يتيح توجيهات أخرى لقراءة القيمة المحرف.
4. مراقبة السمات المحرف: مراقبة التغييرات في قيم السمات من خلال attr. $ reberve ، بما في ذلك الاستيفاء (على سبيل المثال ، src = "{{bar}}"). ليس فقط هو فعال للغاية ، ولكنه أيضًا الطريقة الوحيدة للحصول على القيمة الحقيقية ببساطة. لأنه خلال مرحلة الارتباط ، لم يتم تعيين الاستيفاء (استبدالها بالقيمة الحقيقية) ، لذلك عند الوصول إليها في هذا الوقت ، تكون النتيجة غير محددة.
<! doctype html> <html lang = "zh-cn" ng-app = "directiveProperty"> <head> <meta charset = "utf-8"> <title> التوجيهية-اختبار الاختبار </title> <style type = "text/css" } </style> </head> <body ng-controller = "myctrl"> <input type = "text" ng-model = "name" value = "myName"/> <p my-attr = "123" directive-p2 attr-alt-.js = "{{{name}} type = "text/javaScript"> </script> <script type = "text/javaScript"> var app = Angular.Module ("DirectiveProperty" ، []) ؛ App.Controller ("myctrl" ، function ($ scope) {$ scope.name = "my little dada" ؛}) ؛ var directivep2 = app.directive ("directivep2" ، function () {return {link: function postLink (scope ، lele ، lattr) {console.log ("myattr:" + lattr.myattr) ؛ // 123 console.log ( Console.log (attrdd قد غيرت القيمة "12. فهم الانتقال والنطاق
غالبًا ما نحتاج إلى بعض المكونات القابلة لإعادة الاستخدام. فيما يلي رمز زائف يوضح كيف يمكن لمكون حوار بسيط العمل.
<button ng click = "show = true"> show </button> <dialog visible = "show" on-cancel = "show = false" on-ok = "show = false ؛ dosomething ()"> body goes: {{username}} هو {{title}}. </dialog>سوف يؤدي النقر فوق الزر "show" إلى فتح مربع الحوار. يحتوي مربع الحوار على عنوان مرتبط بالبيانات "اسم المستخدم" ، وهناك أيضًا فقرة نريد وضعها داخل مربع الحوار.
فيما يلي تعريف قالب مكتوب لحوار:
<div ng-show = "show ()"> <h3> {{title}} </h3> <div ng-transclude> </viv> <viv> <button ng click = "onok ()"هذا لن يقدم بشكل صحيح ما لم نفعل بعض المعاملة الخاصة في النطاق.
المشكلة الأولى التي نحتاج إلى حلها هي أن قالب الحوار يتوقع تحديد العنوان وسيتم ربطه باسم المستخدم عند تهيئته. بالإضافة إلى ذلك ، يتطلب الزر وظيفتين Onok و Oncancel لتظهر في النطاق. هذا يحد من فائدة القطعة ..). لحل مشكلة التعيين ، يتم إنشاء المتغيرات المحلية المتوقعة حسب القالب بواسطة الأساليب المحلية التالية (السكان المحليين ، والتي تقدر النطاق في قالب تعريف التوجيه):
النطاق: {title: 'bind' ، // إعداد العنوان لقبول ربط البيانات onok: 'التعبير' ، // إنشاء وظيفة oncancel oncancel: "التعبير" ، // إنشاء دالة Oncancel مندوب:إنشاء خصائص محلية في نطاق التحكم يجلب مشكلتين:
1. العزلة (عزل السمة؟) - إذا نسي المستخدم تعيين عنوان سمة العنصر في قالب التحكم ، فسيكون العنوان مرتبطًا بالسمة "عنوان" نطاق الأجداد (إن وجد). هذا لا يمكن التنبؤ به وغير مرغوب فيه.
2. Transclusion - يمكن لـ DOM المترجمة عرض السكان المحليين (عزل النطاق؟) للتحكم. سيقوم السكان المحليون بتجاوز الخصائص التي تحتاج حقًا إلى الالتزام في عملية النقل. في مثالنا ، تدمر خاصية العنوان الموجودة في البرنامج المساعد خاصية عنوان النقل.
لحل مشكلة عدم وجود عزل السمة ، نحتاج إلى تحديد نطاق معزول لهذا التوجيه. لا يتم توريث النطاق المعزول من النموذج الأولي من نطاق الطفل (لماذا هو نطاق الطفل؟ أليس نطاق الوالدين؟) لذلك لا داعي للقلق بشأن قضايا الصراع السمة (بصفتها شقيق النطاق الحالي).
ومع ذلك ، فإن النطاق المعزول يجلب مشكلة جديدة: إذا كان DOM المترجم هو طفل من نطاق القطعة المعزولة ، فلن يكون قادرًا على ربط أي شيء. لذلك ، فإن النطاق المترجم هو نطاق طفل للنطاق الأصلي الذي تم إنشاؤه قبل أن ينشئ التحكم النطاق المعزول للممتلكات المحلية. ينتمي النطاق المترجم والمعزول إلى عقدة الأخوة (في شجرة النطاق).
قد يبدو هذا معقدًا بعض الشيء بشكل غير متوقع ، لكن القيام بذلك يجلب مفاجآت على الأقل للتحكم في المستخدمين والتحكم في المطورين. (تم حل المشكلة)
لذلك ، فإن تعريف التوجيه النهائي تقريبًا على النحو التالي:
TransClude: TRUE ، النطاق: {title: 'bind' ، // إعداد العنوان لقبول ربط البيانات onok: 'Expression' ، // إنشاء وظيفة oncancel oncancel مندوب: "التعبير" ، // إنشاء دالة Oncancel مندوب: 'accessor' // إنشاء وظيفة getter/setter للعلامة. // لقد جربت هذا ، لكنه فشل ... يرجى الاستمرار في القراءة}لقد حاولت تجميع الكود أعلاه في مثال كامل. إذا قمت بنسخها مباشرة ، فلن يتم تحقيق النتائج المتوقعة. ولكن بعد القليل من التعديل ، يمكن تشغيل المكون الإضافي.
<! doctype html> <html ng-app = "dialog"> <head> <meta http-equiv = "content-type" content = "text/html ؛ charset = utf-8"/> <title> directive-dialog </title> src = "../ angular.js" type = "text/javaScript"> </script> </head> <body> <div ng-controller = "myctrl"> <button ng-click = "show = true"> show </button> <dialog poxible = "{{show}} on-cancel =" show} ON-OK = "show = false ؛ methodInparentsCope () ؛"> <!-يتم الإشارة إلى ما ورد أعلاه على العقد و OK من خلال نطاق التوجيه. إذا كان التعبير يحتوي على وظيفة ، فأنت بحاجة إلى ربط الوظيفة في نطاق الوالدين (حاليًا نطاق myctrl) -> يذهب الجسم إلى هنا: اسم المستخدم: {{username}} ، العنوان: {{title}}. <ul> <!-يمكنك أيضًا اللعب مثل هذا هنا ~ الأسماء هي نطاق الوالدين-> <li ng-repeat = "name in names"> {{name}} </li> </ul> </sialog> </div> <script type = "text/javascript"> var mymodule.module ("dialog" ، []) ؛ mymodule.controller ("myctrl" ، الوظيفة (scope $) {$ scope.names = ["name1" ، "name2" ، "name3"] ؛ $ scope.show = false ؛ $ scope.username = "lclao" ؛ $ scope.title = "$ truct لعبت في نطاق الوالدين !!! ") ؛} ؛}) ؛ mymodule.directive ('Dialog' ، Function Factory () {return {properior: 100 ، template: ['<div ng-show = "visible">' ، '<h3> {{title}}} </h3>' ، '<div ng-transclude> </div>' ، ng-click = "oncancel ()"> إغلاق </button> '،' </div> '،' </div> '،' </div>]. يشير نموذج دالة Wrapper: "&" ، // استخدام نموذج دالة Wrapper ، محتوى الخاصية على العجلات لعلامة الحوار المرئية: "@" // يشير إلى قيمة الخاصية المرئية لعلامة الحوار}}) ؛ </script> </body> </html>13. إنشاء مكونات
عادةً ما نتوقع استبدال التوجيه من خلال بنية DOM معقدة (يوجد العنصر؟ ربما يكون الغرض هو جعل التوجيه النقاط المعقدة الداخلية ، والتي تبدو نقاط رائعة @_ @). هذا يجعل التوجيه اختصارًا لبناء التطبيقات باستخدام مكونات قابلة لإعادة الاستخدام.
فيما يلي مثال على مكون قابل لإعادة الاستخدام:
<! doctype html> <html ng-app = "zippymodule"> <head> <meta http-equiv = "content-type" content = "text/html ؛ charset = utf-8"/> <title> zippymodule </titw <style type = "text/css"> .zippy {border: 1px solid Black ؛ العرض: كتلة مضمنة. العرض: 250 بكسل ؛ } .zippy.opened> .title: قبل {content: '' ؛ } .zippy.opened> .body {display: block ؛ } .zippy.closed > .title:before { content: '► '; } .zippy.closed > .body { display: none; } .zippy > .title { background-color: black; color: white; padding: .1em .3em; cursor: pointer; } .zippy > .body { padding: .1em .3em; } </style> <script src="../angular.js" type="text/javascript"></script></head><body> <div ng-controller="MyCtrl"> Title: <input ng-model="title" type="text"><br/> Text: <textarea ng-model="text"></textarea> <hr/> <div zippy-title="Details: {{title}}...">{{text}}</div> </div> <script type="text/javascript"> var myModule = angular.module("ZippyModule", []); myModule.controller("MyCtrl", function ($scope) { $scope.title = "Here is the title"; $scope.text = "Here is the content... "; }); myModule.directive('zippy', function () { return { template: '<div>' + ' <div>{{title}}</div>' +//This title belongs to the property of the current direct isolate scope ' <div ng-transclude></div>' + //What is here, what is obtained is the property of the parent scope '</div>', replace:true, transclude: true, restrict:'C', scope:{ title:"@zippyTitle"//Bind the zippy-title attribute on the directive element}, link:function(scope,element,attrs) { var title = angular.element(element.children()[0]), opened = false; title.bind("click", toogle); element.addClass("closed"); function toogle() { opened = !opened; element.removeClass(opened ? "closed" : "opened"); element.addClass(opened ? "opened" : "closed"); } } }; }); </script></body></html>