it-swarm.asia

Angular شبيبة: ما هي الحاجة إلى وظيفة رابط التوجيه عندما كان لدينا بالفعل تحكم التوجيه مع نطاق؟

أحتاج إلى إجراء بعض العمليات على النطاق والقالب. يبدو أنه يمكنني القيام بذلك إما في دالة link أو في دالة controller (نظرًا لأن كلاهما لديه حق الوصول إلى النطاق).

متى يكون هذا هو الحال عندما يتعين علي استخدام دالة link وليس وحدة التحكم؟

angular.module('myApp').directive('abc', function($timeout) {
    return {
        restrict: 'EA',
        replace: true,
        transclude: true,
        scope: true,
        link: function(scope, elem, attr) { /* link function */ },
        controller: function($scope, $element) { /* controller function */ }
    };
}

أيضًا ، أفهم أن link هو العالم غير الزاوي. لذلك ، يمكنني استخدام $watch و $digest و $apply.

ما أهمية الدالة link ، عندما كان لدينا بالفعل جهاز تحكم؟

191
Yugal Jindle

بعد أن واجهت الأولي صراعًا مع الدالتين link و controller وقرأت الكثير عنهما ، أعتقد الآن أن لديّ الإجابة.

أولاً يتيح فهم ،

كيف تعمل التوجيهات الزاويّة باختصار:

  • نبدأ مع قالب (كسلسلة أو تحميلها إلى سلسلة)

    var templateString = '<div my-directive>{{5 + 10}}</div>';

  • الآن ، يتم التفاف هذا templateString باعتباره عنصر الزاوية

    var el = angular.element(templateString);

  • باستخدام el ، نجمعها الآن مع $compile لاستعادة وظيفة link.

    var l = $compile(el)

    هنا ما يحدث ،

    • $compile يمر عبر القالب بأكمله ويجمع كل التوجيهات التي يتعرف عليها.
    • جميع التوجيهات التي يتم اكتشافها هي {مترجمة بشكل متكرر ويتم تجميع وظائف link الخاصة بهم.
    • بعد ذلك ، يتم التفاف جميع وظائف link في دالة link جديدة وإعادتها كـ l.
  • أخيرًا ، نوفر وظيفة scope لهذه الدالة l (link) التي تنفذ وظائف الارتباط المُلف مع هذا scope والعناصر المقابلة لها.

    l(scope)

  • هذا يضيف template كعقدة جديدة إلى DOM ويستدعي controller الذي يضيف ساعاته إلى النطاق الذي تتم مشاركته مع القالب في DOM.

enter image description here

مقارنة ترجمة vs ارتباط vs تحكم:

  • كل توجيهات هي {مترجمة مرة واحدة فقط ويتم الاحتفاظ بوظيفة {link لإعادة استخدامها. لذلك ، إذا كان هناك شيء قابل للتطبيق على جميع مثيلات التوجيه ، فيجب أن يتم تنفيذه داخل وظيفة compile الخاصة بالتوجيه.

  • الآن ، بعد التحويل البرمجي ، لدينا link وظيفة يتم تنفيذها أثناء إرفاق القالب بـ DOM. لذلك ، نحن نؤدي كل ما هو خاص بكل مثيل من التوجيه. على سبيل المثال: (إرفاق الأحداث ، تغيير القالب على أساس النطاق ، إلخ.

  • أخيرًا ، يُفترض أن يكون {جهاز التحكم متاحًا ليكون حيًا وسريع التفاعل بينما يعمل التوجيه على DOM (بعد الحصول على مرفق). وبالتالي:

    (1) بعد إعداد العرض [V] (أي القالب) مع رابط. $scope هو [M] و $controller هو لدينا [C] في M V C

    (2) الاستفادة من 2-way الربط بـ نطاق $ عن طريق إعداد الساعات.

    (3) $scope من المتوقع أن تتم إضافة الساعات في وحدة التحكم لأن هذا هو ما يشاهد القالب أثناء وقت التشغيل.

    (4) أخيرًا ، يستخدم controller أيضًا لتكون قادرًا على التواصل بين التوجيهات ذات الصلة. (مثل مثال myTabs في https://docs.angularjs.org/guide/directive )

    (5) صحيح أننا استطعنا القيام بكل هذا في link ظيفة كذلك ولكن عن فصل المخاوف.

لذلك ، أخيرًا لدينا ما يلي الذي يناسب جميع القطع تمامًا:

enter image description here

291
Yugal Jindle

لماذا هناك حاجة إلى وحدات التحكم

يبدأ الفرق بين linkو controllerفي العمل عندما تريد تداخل التوجيهات في DOM الخاص بك وفضح وظائف API من التوجيه الأصل إلى التوجيهات المتداخلة.

من المستندات :

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

قل أنك تريد أن يكون لديك توجيهان my-form و my-text-input وتريد أن يظهر توجيه my-text-input فقط داخل my-form وليس في أي مكان آخر.

في هذه الحالة ، ستقول أثناء تعريف التوجيه my-text-input أنه يتطلب وحدة تحكم من عنصر DOM parentباستخدام الوسيطة requireNAME_ ، مثل هذا: require: '^myForm'. الآن ستكون وحدة التحكم من العنصر الأصل injectedفي دالة linkكوسيطة الرابعة ، بعد $scope, element, attributes. يمكنك استدعاء وظائف على وحدة التحكم هذه والتواصل مع توجيه الوالدين.

علاوة على ذلك ، إذا لم يتم العثور على وحدة تحكم كهذه ، فسيظهر خطأ.

لماذا استخدام الرابط على الإطلاق

ليست هناك حاجة حقيقية لاستخدام دالة linkإذا كان أحدهم يحدد controllerنظرًا لأن $scope متاح في controllername__. علاوة على ذلك ، أثناء تعريف كل من linkو controller، يحتاج المرء إلى توخي الحذر بشأن ترتيب استدعاء الاثنين (يتم تنفيذ controllerمن قبل).

ومع ذلك ، تمشيا مع Angular way ، تتم معظم عمليات معالجة DOM والتجليد ثنائي الاتجاه باستخدام $watchers عادة في دالة linkبينما يتم تنفيذ API for children ومعالجة $scope في controllername__. هذه ليست قاعدة ثابتة وسريعة ، لكن القيام بذلك سيجعل الكود أكثر نموذجية ويساعد في فصل المخاوف (وحدة التحكم ستحتفظ بحالة directiveوستحافظ الدالة linkعلى DOM+ الروابط الخارجية).

72
musically_ut

تمثل الدالة/الكائن controllerوحدة تحكم في نموذج عرض التجريد (MVC). على الرغم من أنه لا يوجد شيء جديد للكتابة عن MVC ، إلا أنه لا يزال أهم مزايا الزاوي: تقسيم المخاوف إلى أجزاء أصغر. وهذا كل شيء ، لا شيء أكثر من ذلك ، لذا إذا كنت بحاجة إلى الرد على التغييرات Modelالتي تأتي من Viewفإن Controllerهو الصحيح الشخصللقيام بهذه المهمة).

القصة حول وظيفة linkمختلفة ، فهي تأتي من منظور مختلف ثم MVC. وضروري للغاية ، بمجرد أن نريد عبور حدود controller/model/view(القالب).

لنبدأ بالمعلمات التي تم تمريرها إلى دالة linkname__:

function link(scope, element, attrs) {
  • النطاق هو كائن نطاقAngular.
  • element هو العنصر ملفوف jqLite يطابق هذا التوجيه.
  • attrs هو كائن له أسماء السمات المقيسة وقيمها المناظرة.

لوضع linkفي السياق ، يجب أن نذكر أن جميع التوجيهات تمر بخطوات عملية التهيئة هذه: ترجمة، رابط. مقتطف من كتاب Brad Green and Shyam Seshadri Angular JS:

مرحلة الترجمة (أخت الرابط ، دعنا نذكرها هنا للحصول على صورة واضحة):

في هذه المرحلة ، Angular يمشي على DOM لتحديد جميع التوجيهات المسجلة في القالب. لكل توجيه ، يقوم بتحويل DOM بناءً على قواعد التوجيه (القالب والاستبدال والاستبدال وما إلى ذلك. ) ، واستدعاء وظيفة الترجمة إن وجدت ، والنتيجة هي وظيفة قالب مترجمة ،

مرحلة الارتباط :

لجعل العرض ديناميكيًا ، يقوم Angular بتشغيل وظيفة ارتباط لكل توجيه. وظائف الارتباط عادة ما تخلق مستمعين على DOM أو النموذج. يحافظ هؤلاء المستمعون على العرض والنموذج متزامنين في جميع الأوقات.

يمكن العثور على مثال لطيف حول كيفية استخدام linkهنا: إنشاء توجيهات مخصصة . راجع المثال: إنشاء توجيه يعالج DOM ، والذي يُدرج "وقت-وقت" في الصفحة ، يتم تحديثه كل ثانية.

مجرد مقتطف قصير جدًا من ذلك rich source أعلاه ، يُظهر التلاعب الحقيقي باستخدام DOM. هناك وظيفة مدمجة في خدمة مهلة $ ، كما يتم محوها في destructorcall لتجنب تسرب الذاكرة

.directive('myCurrentTime', function($timeout, dateFilter) {

 function link(scope, element, attrs) {

 ...

 // the not MVC job must be done
 function updateTime() {
   element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
 }

 function scheduleUpdate() {
   // save the timeoutId for canceling
   timeoutId = $timeout(function() {
     updateTime(); // update DOM
     scheduleUpdate(); // schedule the next update
   }, 1000);
 }

 element.on('$destroy', function() {
   $timeout.cancel(timeoutId);
 });

 ...
15
Radim Köhler