[javascript] كيف يعمل ربط البيانات في AngularJS؟



Answers

قدمت Misko بالفعل وصفًا ممتازًا لكيفية عمل ارتباطات البيانات ، لكنني أود إضافة وجهة نظري حول مشكلة الأداء مع ربط البيانات.

كما ذكر Misko ، حوالي 2000 الارتباطات حيث تبدأ في رؤية المشاكل ، ولكن لا ينبغي أن يكون لديك أكثر من 2000 قطعة من المعلومات على صفحة على أي حال. قد يكون هذا صحيحًا ، لكن ليس كل ارتباط للبيانات مرئي للمستخدم. بمجرد البدء في إنشاء أي نوع من عناصر واجهة المستخدم أو شبكة البيانات مع التجليد ثنائي الاتجاه ، يمكنك بسهولة الوصول إلى 2000 رابط ، دون الحاجة إلى ux سيئة.

ضع في اعتبارك ، على سبيل المثال ، combobox حيث يمكنك كتابة نص لتصفية الخيارات المتوفرة. يمكن أن يكون هذا النوع من التحكم يحتوي على 150 عنصرًا وما زال صالحًا للاستخدام. إذا كان يحتوي على بعض الميزات الإضافية (على سبيل المثال فئة محددة على الخيار المحدد حاليًا) ، فستبدأ في الحصول على ارتباطات 3-5 لكل خيار. ضع ثلاثة من هذه الأدوات على الصفحة (على سبيل المثال ، اختر بلدًا ، والآخر لاختيار مدينة في البلد المذكور ، والثالث لتحديد فندق) وكنت في مكان ما بين 1000 و 2000 ارتباطات بالفعل.

أو النظر في شبكة البيانات في تطبيق ويب الشركات. 50 صف في كل صفحة ليس من غير المعقول ، كل منها يمكن أن يكون 10-20 عمود. إذا قمت ببناء هذا باستخدام ng-repeats ، و / أو لديك معلومات في بعض الخلايا التي تستخدم بعض الارتباطات ، قد تقترب من 2000 الارتباطات مع هذه الشبكة بمفردها.

أجد أن هذه مشكلة كبيرة عند العمل مع AngularJS ، والحل الوحيد الذي تمكنت من العثور عليه حتى الآن هو إنشاء عناصر واجهة مستخدم دون استخدام ربط ثنائي الاتجاه ، بدلاً من استخدام ngOnce ، أو إلغاء تسجيل المراقبين والحيل المماثلة ، أو بناء التوجيهات مما ينشئ DOM مع معالجة jQuery و DOM. أشعر أن هذا يهزم الهدف من استخدام Angular في المقام الأول.

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

TL، DR
يمكن أن يتسبب ربط البيانات في حدوث مشكلات في الأداء على الصفحات المعقدة.

Question

كيف يعمل ربط البيانات في إطار AngularJS ؟

لم أجد تفاصيل فنية على موقعهم . من الواضح أكثر أو أقل كيف يعمل عندما يتم نشر البيانات من العرض إلى النموذج. ولكن كيف يتتبع AngularJS تغييرات خصائص النموذج دون الحاصلين على الجوائز؟

لقد وجدت أن هناك مراقبي جافا سكريبت يمكنهم القيام بهذا العمل. ولكنها غير معتمدة في Internet Explorer 6 و Internet Explorer 7 . إذن كيف يعرف AngularJS أنني غيرت على سبيل المثال ما يلي وعكست هذا التغيير في طريقة العرض؟

myobject.myproperty="new value";



  1. ربط البيانات أحادي الاتجاه هو نهج يتم فيه أخذ قيمة من نموذج البيانات وإدراجها في عنصر HTML. لا توجد طريقة لتحديث نموذج من العرض. يتم استخدامه في أنظمة القالب الكلاسيكي. هذه الأنظمة تربط البيانات في اتجاه واحد فقط.

  2. ربط البيانات في تطبيقات Angular هو التزامن التلقائي للبيانات بين النموذج ومكونات العرض.

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




في ما يلي مثال لربط البيانات مع AngularJS ، باستخدام حقل إدخال. سأشرح لاحقا

كود HTML

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

AngularJS رمز

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

كما ترون في المثال أعلاه ، تستخدم AngularJS ng-model للاستماع ومشاهدة ما يحدث على عناصر HTML ، خاصة في حقول input . عندما يحدث شيء ما ، افعل شيئًا. في حالتنا ، يرتبط ng-model برأينا ، باستخدام علامة الشارب {{}} . يتم عرض أي شيء يتم كتابته داخل حقل الإدخال على الشاشة على الفور. وهذا هو جمال ربط البيانات باستخدام AngularJS في أبسط صوره.

أتمنى أن يساعدك هذا.

شاهد مثالًا Codepen هنا على Codepen




تعالج AngularJS آلية ربط البيانات بمساعدة ثلاث وظائف قوية: $watch() ، $digest() و $apply() . في معظم الأوقات ، ستستدعي AngularJS نطاق $. $ watch () ونطاق $. $ digest () ، ولكن في بعض الحالات قد تضطر إلى استدعاء هذه الوظائف يدويًا لتحديثها بقيم جديدة.

$ watch () : -

يتم استخدام هذه الوظيفة لمراقبة التغييرات في متغير على نطاق $. يقبل ثلاث معلمات: التعبير ، المستمع وكائن المساواة ، حيث يكون عنصر المستمع والمساواة معلمات اختيارية.

$ digest () -

تتكرر هذه الدالة عبر كافة الساعات الموجودة في كائن نطاق $ ، وكائنات نطاق $ التابعة الخاصة به
(إذا كان لديه أي). عندما يتكرر $ digest () على الساعات ، فإنه يتحقق مما إذا تم تغيير قيمة التعبير. إذا تغيرت القيمة ، فإن AngularJS يستدعي المستمع بقيمة جديدة وقيمة قديمة. يتم استدعاء الدالة $ digest () عندما يعتقد AngularJS أنه ضروري. على سبيل المثال ، بعد النقر على زر ، أو بعد مكالمة AJAX. قد يكون لديك بعض الحالات التي لا يقوم فيها AngularJS باستدعاء الدالة $ digest () نيابة عنك. في هذه الحالة عليك أن تسميها بنفسك.

$ apply () -

يقوم Angular بإجراء التحديثات التلقائية السحرية فقط بتغييرات الطراز الموجودة داخل سياق AngularJS. عندما تقوم بالتغيير في أي نموذج خارج السياق الزاوي (مثل أحداث DOM للمتصفح ، setTimeout ، XHR أو مكتبات الطرف الثالث) ، فأنت بحاجة إلى إعلام Angular بالتغييرات عن طريق استدعاء $ apply () يدويًا. عند انتهاء استدعاء الدالة $ () التطبيق () المكالمات AngularJS $ digest () داخليًا ، بحيث يتم تحديث كافة عمليات ربط البيانات.




هذا هو فهمي الأساسي. قد يكون من الخطأ!

  1. يتم مراقبة العناصر عن طريق تمرير وظيفة (إرجاع الشيء المراد مراقبته) إلى طريقة $watch .
  2. يجب إجراء التغييرات على العناصر المراقبة ضمن كتلة من الشفرة ملفوفة بطريقة $apply .
  3. في نهاية $apply يتم $apply طريقة $digest التي تمر عبر كل من الساعات والشيكات لمعرفة ما إذا تغيرت منذ آخر مرة تم تشغيل $digest .
  4. إذا تم العثور على أي تغييرات ثم يتم استدعاء الخلاصة مرة أخرى حتى تستقر جميع التغييرات.

في التطور الطبيعي ، يخبر تركيب ربط البيانات في HTML المترجم AngularJS بإنشاء الساعات لك ، ويتم تشغيل أساليب المتحكم داخل $apply بالفعل. لذلك مطور التطبيق هو كل شفاف.




شرح مع الصور:

ربط البيانات يحتاج إلى رسم الخرائط

المرجع في النطاق ليس بالضبط المرجع في القالب. عندما تقوم بربط كائنين ببيانات ، فإنك تحتاج إلى كائن ثالث يستمع إلى الآخر ويقوم بتعديل الآخر.

هنا ، عند تعديل <input> ، تلمس بيانات ref3 . وستعمل الآلية الكلاسيكية المرتبطة بالبيانات على تغيير بيانات ref4 . إذاً كيف ستنقل تعبيرات {{data}} ؟

الأحداث تؤدي إلى $ digest ()

يحافظ الزاوي على قيمة oldValue newValue لكل ارتباط. وبعد كل حدث Angular ، ستقوم حلقة $digest() الشهيرة بالتحقق من WatchList لمعرفة ما إذا تغير شيء ما. هذه الأحداث الزاويّة هي ng-click ، ng-change ، $http completed… The $digest() ستعمل طالما أن أي oldValue يختلف عن newValue .

في الصورة السابقة ، ستلاحظ أن البيانات ref1 و data-ref2 قد تغيرت.

الاستنتاجات

انها قليلا مثل البيض والدجاج. أنت لا تعرف أبدا من يبدأ ، ولكن نأمل أن يعمل في معظم الوقت كما هو متوقع.

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




Related