1. ما هو النطاق؟
Scope (http://code.angularjs.org/1.0.2/docs/api/ng.drootscope.scope) هو كائن يشير إلى نموذج التطبيق. إنه أيضًا سياق تنفيذ التعبير (http://www.cnblogs.com/lclao/archive/2012/09/16/2687162.html). يتم وضع النطاق في التسلسل الهرمي لهياكل DOM مماثلة لتلك الخاصة بالتطبيق. يمكن للنطاق مراقبة (Watch ، $ Watch) أحداث التعبير والانتشار.
2. خصائص النطاق
3. النطاق كنموذج بيانات (نطاق كنموذج للبيانات)
النطاق هو الارتباط بين وحدة تحكم التطبيق والعرض. في مرحلة ربط القالب (http://www.cnblogs.com/lclao/archive/2012/09/04/2669802.html) ، التوجيه (http://www.cnblogs.com/lclao/archive/2012/09/09/26719 نِطَاق. تتيح Watch $ التوجيه بمعرفة التغييرات في السمات ، لذا فإن التوجيه يجعل القيمة المحدثة في DOM.
كل من وحدات التحكم والتوجيهات لها إشارة إلى النطاق ، ولكن ليس لبعضها البعض. هذا الترتيب يفصل وحدة التحكم عن التوجيه و DOM. هذا مكان مهم لأنه يعزل وحدة التحكم عن الرأي ، مما يحسن بشكل كبير قصة اختبار التطبيقات.
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> نموذج البيانات </title> <style type = "text/css"> .ng-cloak {display: none ؛ } </style> </head> <body> <div ng-controller = "myController"> اسمك: <input type = "text" ng-model = "username"/> <button ng-click = "sayhello ()" type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.username = "my little dada" ؛ $ scope.sayhello = function () {$ scope.greeting = "hello ~" + $ scope.username + "!" ؛ } ؛ } </script> </body> </html>في المثال أعلاه ، يمكننا أن نلاحظ أن MyController يعين سمة اسم المستخدم في نطاق مع "My Little Dada". بعد ذلك ، يقوم Scope بإعلام المدخلات للتعيين وإملاء قيمة اسم المستخدم مسبقًا في الإدخال. هذا يوضح كيف يمكن لجهاز التحكم كتابة البيانات في النطاق.
وبالمثل ، يمكن لجهاز التحكم إرفاق السلوك بالنطاق ، تمامًا مثل طريقة Sayhello التي يتم تشغيلها عندما ينقر المستخدم على زر "الترحيب". يمكن أن تقرأ طريقة Sayhello سمة اسم المستخدم أو إنشاء سمة تحية. هذا يدل على أنه عندما تكون مرتبطة بتحكم في إدخال HTML ، يتم تحديث الخصائص في نطاقها تلقائيًا.
من الناحية المنطقية ، يتضمن عرض {{تحية}} النقطتين التاليتين:
Search Scope مع Template DOM Node التي تحدد التعبير {{تحية}}. في هذا المثال ، هذا النطاق هو نفس النطاق الذي تم تمريره إلى MyController. (سنناقش النطاق الهرمي لاحقًا)
يتم تقييم تعبير التحية من خلال النطاق الذي تم استرداده مسبقًا ، ثم يتم استخدام النتيجة كقيمة للنص الذي يحيط بعنصر DOM.
يمكننا أن نعتقد أنه يمكن استخدام Scope وخصائصه الخاصة كبيانات لتقديم طرق العرض. النطاق هو المصدر الفردي لجميع الأشياء ذات الصلة.
من منظور قابلية الاختبار ، يسعد فصل وحدة التحكم والعرض ، لأنه يتيح لنا (التركيز على) اختبار السلوك دون تدخل في تقديم تفاصيل.
IT ('يجب أن يقول hello' ، function () {var scopemock = {} ؛ var cntl = new MyController (scopemock) ؛ // التأكيد على أن اسم المستخدم يتوقع مسبقًا (scopemock.username) .tequal ('world') ؛ توقع (scopemock.greeting). إلى toequal ('Hello Angular!') ؛}) ؛4. التسلسلات الهرمية النطاق (التسلسلات الهرمية النطاق)
كل تطبيق زاوي يحتوي على نطاق جذر واحد فقط ، ولكن يمكن أن يكون له نطاقات أطفال متعددة.
يمكن أن يحتوي التطبيق على العديد من نطاقات الأطفال ، لأن بعض التوجيهات ستقوم بإنشاء نطاقات جديدة للأطفال (انظر الوثائق التوجيهية لمعرفة التوجيهات التي يمكن أن تنشئ نطاقات جديدة ، مثل NG-Repeat). عند إنشاء النطاق الجديد ، سيتم إضافتها إلى نطاق الوالدين كنطاق طفل. وبهذه الطريقة ، يتم إنشاء بنية شجرة مشابهة لـ DOM التي يتم إرفاقها.
عندما يقوم Angular بتقييم {{username}} ، فإنه ينظر أولاً إلى خاصية اسم المستخدم للنطاق المرتبط بالعنصر الحالي. إذا لم يتم العثور على خاصية مقابلة ، فسيبحث عن نطاق الوالدين حتى يصل إلى نطاق الجذر. في JavaScript ، يسمى هذا السلوك "ميراث النموذج الأولي" ، وعادة ما يكون نطاق الطفل ورثًا من والدهم.
يوضح هذا المثال النطاق (ما هو) وميراث النموذج الأولي للخصائص في التطبيق.
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> scope hierarchies </itht> <style type = "text/css"> .ng-cloak {display: none ؛ . } </style> </head> <body> <div ng-controller = "myController"> المدير: {{keameee.name}} </ul> <hr/> {{Greeting}} </div> <script src = "../ Angular 1.0.1.js" type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.department = $ scope.employee = {name: "my little dada" ، التقارير: [{name: "lclao"} ، {name: "who^o^"}]} ؛ } </script> </body> </html>لاحظ أن Angular يضع تلقائيًا فئة NG-Scope في عناصر تلتزم النطاق. يتم تعريف <style> في المثال أعلاه ، مع تسليط الضوء على نطاق النطاق الجديد من خلال الخط المنقط الأحمر. نظرًا لأن المكرر يقوم بتقييم التعبير {{{keameee.name}} ، فإن نطاق الطفل ضروري ، ولكن اعتمادًا على نطاق التقييم الذي يتم تقييمه ، فإن النطاقات المختلفة لها نتائج مختلفة. وبالمثل ، فإن قيمة {{Department}} ورثت من النموذج الأولي في نطاق الجذر. فقط عندما يكون هناك ، يمكن تعريف سمة القسم.
5. استرداد النطاقات من DOM (استرداد النطاق من DOM)
يتم توصيل النطاق بـ DOM كسممة بيانات النطاق $ ويمكن استخدامها لاسترجاعها لأغراض تصحيح الأخطاء. (من المستحيل استرداد النطاق بهذه الطريقة في التطبيق.) يتم تعريف موقع نطاق الجذر المرتبط بـ DOM بواسطة موقع توجيه NG-APP. عادةً ما يتم وضع NG-APP في عنصر <html> ، ولكن يمكن أيضًا وضعه في عناصر أخرى ، على سبيل المثال ، لا يحتاج سوى جزء من العرض إلا إلى السيطرة عليه بواسطة Angular.
عرض النطاق في تصحيح الأخطاء:
1. في المتصفح ، انقر بزر الماوس الأيمن على العنصر الذي تهتم به وحدد "عرض العنصر". يمكننا أن نرى أن تصحيح تصحيح المستعرض يسلط الضوء على العناصر التي اخترناها.
2. يتيح لنا Debugger الوصول إلى العنصر المحدد حاليًا من خلال متغير $ 0 في وحدة التحكم.
3. إذا كنت ترغب في عرض النطاق المرتبط ، فيمكننا إدخال: Angular.Element ($ 0) .scope () في وحدة التحكم
6. انتشار أحداث النطاق (انتشار حدث النطاق)
يمكن للنطاق نشر الأحداث بطريقة تشبه أحداث DOM. يمكن بث الأحداث (http://code.angularjs.org/1.0.2/docs/api/ng.drootscope.scope#$Broadcast) إلى Scope أو Emit (http://code.angularjs.org/1.2/docs/api/ng.crotscope. (إذا تم الاستماع إلى النطاق الحالي ، فسيتم تنفيذه أيضًا)
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> scope-event-propagation </title> <style type = "text/css"> .ng-cloak {display: none ؛ } </style> </head> <body> <div ng-controller = "myController"> عدد نطاق الجذر: {{count}} <ul> <li ng-repeat = "i in [1] ng-click = "$ broadcast ('myevent')"> $ broadcast ("myevent") </button> <br/> عدد النطاق الأوسط: {{count}} <ul> <li ng-repeat = "item in [1،2] </ul> </viv> <script src = "../ Angular-1.0.1.js" type = "text/javaScript"> </script> <script type = "text/javaScript"> function myController ($ scope) {$ scope.count = 0 ؛ $ scope. $ on ("myevent" ، function () {$ scope.count ++ ؛}) ؛ } </script> </body> </html>7. دورة حياة النطاق (دورة حياة النطاق)
في دفق الحدث العادي للمتصفح ، عندما يتلقى المتصفح الحدث ، فإنه سيقوم بتنفيذ رد اتصال JavaScript المقابل. بمجرد تنفيذ وظيفة رد الاتصال ، سيقوم المتصفح بإعادة رسم DOM والعودة إلى الحالة حيث تستمر في انتظار الحدث.
عندما يستدعي المتصفح رمز JavaScript خارج بيئة التنفيذ الزاوي ، فإن هذا يعني أن Angular لا يعرف تغيير النموذج. للتعامل بشكل صحيح مع تعديل النموذج ، يجب أن يدخل هذا الأمر بيئة التنفيذ الزاوي عن طريق جعل طريقة تطبيق $. فقط عندما يتغير النموذج في طريقة تطبيق $ سيتم حسابه بشكل صحيح بواسطة Angular. على سبيل المثال ، يستمع التوجيه لحدث DOM ، مثل NG-Click ، والذي يجب تقييم التعبير في طريقة تطبيق $.
بعد تقييم التعبير ، تنفذ طريقة تطبيق $ A $ Digest. في مرحلة $ Digest ، يقوم Scope بفحص جميع التعبيرات التي تم الاستماع إليها بواسطة $ watch ، ويقارن القيمة الحالية بالقيمة القديمة. التحقق القذر غير متزامن. هذا يعني أن بيان المهمة (على سبيل المثال ، Scope.Username = "Angular") لن يتسبب على الفور في إخطار ساعة $ ، ولكن سيتم تأخير الإخطار بساعة $ إلى مرحلة $ Digest. يعد هذا التأخير ضروريًا لأنه يجمع بين تحديثات النماذج المتعددة في إشعار Watch $ ، مما يضمن عدم تنفيذ أي ساعة $ أخرى أثناء عملية إشعار الساعة. إذا غيرت ساعة $ قيمة النموذج ، فسوف يجبرها زيادة دورة $ digest.
1) الخلق (إنشاء نطاق)
يتم إنشاء نطاق الجذر بواسطة $ enjector (http://code.angularjs.org/1.0.2/docs/api/auto.undinjector) أثناء عملية بدء تشغيل التطبيق. أثناء عملية ربط القالب ، ستنشئ بعض التوجيهات نطاقًا جديدًا للطفل.
2) تسجيل المراقب (مراقب التسجيل)
أثناء عملية ربط القالب ، سجلات التوجيه $ watch في النطاق. سيتم استخدام هذه الساعات كقيمة نشر النموذج إلى DOM.
3) طفرة النموذج (تغييرات النموذج)
لكي يتم اكتشاف التغييرات بشكل صحيح ، نحتاج إلى لفها في نطاق. $. (قامت واجهة برمجة التطبيقات الزاوية بذلك ضمنيًا ، لذلك عند القيام بعمل متزامن في وحدة التحكم أو العمل غير المتزامن مع $ http أو $ timeout ، لا يلزم إجراء مكالمة إضافية $).
4) مراقبة الطفرة (مراقبة التغيير)
في نهاية $ تطبيق ، سوف يقوم Angular بتنفيذ دورة $ Digest في نطاق الجذر ، والتي ستنتشر إلى جميع نطاقات الأطفال. في دورة $ Digest ، سيتم التحقق من جميع التعبيرات أو الوظائف المسجلة لدى $ watch لتحديد ما إذا كان النموذج قد تغير. في حالة حدوث التغيير ، سيتم استدعاء مستمع Watch $ المقابل.
5) تدمير النطاق (تدمير النطاق)
عندما لم يعد نطاق الطفل ضروريًا ، تقع على عاتق منتج نطاق الطفل أن يدمرهم من خلال النطاق. $ Dorn () API. سيؤدي ذلك إلى إيقاف انتشار استدعاء $ Digest في نطاق الطفل ، بحيث يمكن إعادة تدوير الذاكرة المستخدمة من قبل نموذج نطاق الطفل بواسطة GC (جامع القمامة).
1. النطاقات والتوجيهات
خلال مرحلة التجميع ، يعتمد برنامج التحويل البرمجي على توجيه قوالب DOM. يمكن عادةً تقسيم التوجيهات إلى فئتين:
مراقبة التوجيهات ، مثل تعبير Dobule-curly {{Expression}} ، قم بتسجيل المستمع باستخدام طريقة ساعة $. عندما يتغير التعبير (القيمة) ، يجب إخطار هذه التوجيهات بتحديث العرض.
توجيه المستمع ، مثل NG-Click ، يسجل مستمعًا في DOM. عندما يقوم مستمع DOM ، بتنفيذ التوجيه التعبير ذي الصلة ويقوم بتحديث العرض باستخدام طريقة تطبيق $.
عند سماع حدث خارجي (مثل إجراء المستخدم أو المؤقت أو XHR) ، يجب تطبيق التعبير ذي الصلة على النطاق من خلال طريقة تطبيق $ ، بحيث يمكن تحديث جميع المستمعين بشكل صحيح.
2. التوجيهات التي تخلق نطاقات
في معظم الحالات ، يؤثر التوجيه والنطاق بشكل متبادل ، ولكن لا يتم إنشاء مثيل نطاق جديد. ومع ذلك ، فإن بعض التوجيهات (مثل NG-Controller و NG-Repeat) تنشئ نطاقًا جديدًا ، مما يؤدي إلى إرفاق نطاق الطفل بعنصر DOM المقابل. ننظر إلى نطاق أي عنصر DOM باستخدام Angular.Element (adomelement) .scope ().
3. وحدات التحكم والنطاقات
في الحالات التالية ، تؤثر النطاق ووحدة التحكم على بعضها البعض:
4. SCOPE $ Watch Performance Assessions (Scope $ Watch Performance Assessions)
في Angular ، إنها عملية شائعة لإجراء فحص قذر على النطاق للكشف عن التغييرات في السمات. للقيام بذلك ، يتطلب ذلك أن تكون وظيفة الفحص القذرة فعالة. كن حذرًا من أن وظائف الفحص القذرة لا تقوم بأي عمليات الوصول إلى DOM ، لأن الوصول إلى DOM هو أوامر ذات حجم أبطأ من الوصول إلى خصائص كائن JavaScript.
ما سبق هو المعلومات حول نطاق AngularJS. سنستمر في إضافة المعلومات ذات الصلة في المستقبل. شكرا لك على دعمك لهذا الموقع!