AngularJS ng-repeat Directive مع مثال

⚡ ملخص ذكي

تُنشئ خاصية ng-repeat في AngularJS نسخة واحدة من العنصر لكل عنصر في مجموعة مُعرّفة في نطاق وحدة التحكم. فهي تُحوّل المصفوفة إلى قائمة أو جدول أو أي ترميز متكرر دون الحاجة إلى كتابة حلقة تكرار يدوية.

  • 🔁 السلوك الأساسي: يقوم ng-repeat باستنساخ العنصر المضيف مرة واحدة لكل عنصر، لذا فإن التوجيه ينتمي إلى العنصر الذي يتم تكراره، وليس إلى حاويته.
  • 🏷️ متغير الحلقة: يصبح الاسم الذي يسبق كلمة "in" اسمًا مستعارًا محليًا للعنصر الحالي داخل تلك النسخة المستنسخة.
  • 🧬 نطاق الطفل: كل تكرار يحصل على نطاق فرعي خاص به، ولهذا السبب فإن تعيين قيمة بدائية داخل الحلقة لا يصل إلى الأصل.
  • 🔑 الهوية Tracking: A tracيخبر التعبير k باستخدام AngularJS بكيفية تحديد العناصر، وهو مطلوب عندما تحتوي المجموعة على قيم متكررة.
  • 🔢 السكان المحليون المدمجون: تتوفر خصائص مثل $index و$first و$last داخل كل تكرار للترقيم والتنسيق.
  • ⚠️ حالة الدعم: وصل AngularJS إلى نهاية عمره الافتراضي في 31 ديسمبر 2021 ولم يعد يتلقى أي تحديثات أمنية أخرى.

توجيه ng-repeat في AngularJS

توجيه ng-repeat في AngularJS

استخدم نانوغرام تكرار توجيهات في AngularJS، تُستخدم خاصية ng-repeat لعرض القيم المتكررة المُعرّفة في وحدة التحكم. أحيانًا نحتاج إلى عرض قائمة من العناصر في واجهة المستخدم، وتقوم ng-repeat بعرض هذه القائمة المُعرّفة في وحدة التحكم على صفحة العرض.

⚠️ إشعار الدعم: وصل AngularJS نهاية الحياة في 31 ديسمبر 2021 ولا يتلقى أي تحديثات أو إصلاحات أمنية إضافية. يبقى التوجيه أدناه دقيقًا لصيانة تطبيقات AngularJS 1.x الحالية؛ في التطبيقات الحديثة زاوي المكافئ هو *ngFor التوجيه الهيكلي.

مثال توجيهي AngularJS ng-repeat

دعونا نلقي نظرة على مثال لتوجيه ng-repeat في AngularJS:

توجيه ng-repeat في AngularJS

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp" ng-controller="DemoController">
    <h1>Topics</h1>
    <ul>
        <li ng-repeat="tpname in TopicNames">
            {{tpname.name}}
        </li>
    </ul>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('DemoController', function($scope) {
        $scope.TopicNames = [
            { name: "What controllers do from Angular's perspective" },
            { name: "Controller Methods" },
            { name: "Building a basic controller" }
        ];
    });
</script>

</body>
</html>

Code التفسير:

  1. في خانة رمز الخصم، أدخل TABBYDAY. مراقب أولاً، نحدد مصفوفة عناصر القائمة التي سيتم عرضها في الواجهة. هنا مصفوفة تسمى TopicNames يحتوي على ثلاثة عناصر، كل منها عبارة عن زوج من الاسم والقيمة.
  2. يتم تعيين المصفوفة مباشرة إلى $scope.TopicNamesمما يجعله متاحًا للعرض المرتبط بهذا المتحكم.
  3. علامات HTML <ul> (قائمة غير مرتبة) و <li> (عنصر القائمة) لعرض العناصر. يقوم توجيه ng-repeat بالتكرار على كل عنصر في المصفوفة، و tpname المتغير المحلي الذي يحتوي على العنصر الحالي، لذلك {{tpname.name}} يطبع خاصية الاسم.

⚠️ تصحيح: أوضح التفسير الأصلي أن المصفوفة "أضيفت إلى متغير عضو يسمى topicsلا يوجد مثل هذا المتغير في الكود - يتم تعيين المصفوفة مباشرةً إلى $scope.TopicNamesوهو الاسم الذي تشير إليه طريقة العرض. إدخال اسم ثانٍ هنا هو سبب شائع لقائمة فارغة.

إذا تم تنفيذ الكود بنجاح، فسيتم عرض المخرجات التالية في المتصفح.

توجيه ng-repeat في AngularJS

وحدات تحكم متعددة AngularJS

رأينا سابقًا وحدة تحكم واحدة تتولى فيها طريقة واحدة كلاً من الجمع والطرحtracبدلاً من التعامل مع الأرقام، يمكنك استخدام وحدات تحكم متعددة لفصل المنطق بشكل أكثر وضوحًا. على سبيل المثال، يمكن لوحدة تحكم واحدة التعامل مع الأرقام بينما تتعامل أخرى مع النصوص.

دعونا نلقي نظرة على مثال لتعريف وحدات تحكم متعددة في تطبيق AngularJS.

وحدات تحكم متعددة AngularJS

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp">
    <div ng-controller="firstcontroller">
        <div ng-controller="secondcontroller">
            {{lname}}
        </div>
    </div>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('firstcontroller', function($scope) {
        $scope.pname = "firstcontroller";
    });

    app.controller('secondcontroller', function($scope) {
        $scope.lname = "secondcontroller";
    });
</script>

</body>
</html>

Code التفسير:

  1. تم تعريف وحدتي تحكم، firstcontroller و secondcontrollerكل منها يُلحق متغيرًا بخاصيته الخاصة نطاق: pname في الأول، lname في الثانية.
  2. في العرض، يكون المتحكم الثاني متداخلًا داخل المتحكم الأول، ويقرأ التعبير lname من النطاق الداخلي. لأن وحدة التحكم المتداخلة ترث من وحدة التحكم الأصلية، {{pname}} سيتم حل الأمر هنا أيضاً — فالإرث يتدفق إلى الأسفل، وليس إلى الأعلى أبداً.

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

وحدات تحكم متعددة AngularJS

كيف تعمل track by with ng-repeat

أكثر حالات فشل ng-repeat شيوعًا هو الخطأ Duplicates in a repeater are not allowedيظهر هذا الخطأ في اللحظة التي تحتوي فيها المجموعة على نفس القيمة مرتين، ويتوقف عرض القائمة تمامًا.

السبب هو الهوية tracيحتاج AngularJS إلى مفتاح ثابت لكل عنصر لكي يتمكن من إعادة استخدام عناصر DOM بدلاً من إعادة بنائها في كل عملية تحديث. يستخدم AngularJS افتراضيًا قيمة العنصر نفسها، مما يؤدي إلى تضارب القيم المتطابقة.

<!-- Fails: the value 2 appears twice -->
<li ng-repeat="n in [1, 2, 2, 3]">{{n}}</li>

<!-- Works: position is unique even when values repeat -->
<li ng-repeat="n in [1, 2, 2, 3] track by $index">{{n}}</li>

<!-- أفضل for records from a server: track by a real identifier -->
<li ng-repeat="topic in TopicNames track by topic.id">{{topic.name}}</li>

إن اختيار أحد الشكلين له أهمية أكبر مما يبدو للوهلة الأولى. Tracking by $index يحل هذا الخطأ دائمًا، لأن الموضع فريد بحكم التعريف، ولكنه يربط كل عقدة DOM بفتحة بدلاً من سجل. ثم تعيد إعادة ترتيب المجموعة أو تصفيتها استخدام العقد الخاطئة، مما يظهر على شكل حقول إدخال محفوظة.ping نص الصف السابق.

Tracking بواسطة مُعرِّف حقيقي مثل topic.id يتجنب ذلك تمامًا. يستطيع AngularJS تتبع كل سجل أثناء انتقاله، لذا فهو يعيد ترتيب العناصر الموجودة بدلًا من حذفها وإعادة بنائها. في القوائم الطويلة، يكون هذا أسرع بشكل ملحوظ، لأن إعادة العرض لا تؤثر إلا على الصفوف التي تغيرت بالفعل. استخدم $index فقط لمصفوفات القيم العادية التي لا يتم إعادة ترتيبها أبدًا.

خصائص مميزة متوفرة داخل ng-repeat

تُعرّض كل دورة من دورات ng-repeat عدة خصائص للقراءة فقط ضمن نطاقها الفرعي. تُحدد هذه الخصائص موقع العنصر الحالي داخل المجموعة، بما في ذلك الترقيم، وأنماط التناوب، والفواصل، دون إضافة أي حالة إضافية إلى وحدة التحكم.

الممتلكات النوع بعد التخفيض
$index رقم الهاتف موضع العنصر الحالي، بدءًا من 0
$first منطقية ينطبق هذا على العنصر الأول فقط
$last منطقية ينطبق هذا على العنصر الأخير فقط
$middle منطقية ينطبق هذا على كل عنصر ليس الأول ولا الأخير
$even منطقية صحيح عندما يكون $index زوجيًا
$odd منطقية صحيح عندما يكون $index فرديًا

يُستخدم عادةً مع فئة ng لرسم خطوط زيبراping، كما في ng-class="{'row-alt': $odd}"أو باستخدام ng-if لعرض فاصل في كل صف باستثناء الصف الأخير، مكتوب ng-if="!$last"إن عرض رقم الصف بطريقة يسهل على الإنسان قراءتها هو ببساطة {{$index + 1}}بما أن الفهرس يبدأ من الصفر، يتم إعادة حساب جميع الخصائص الست تلقائيًا كلما تغيرت المجموعة، لذا لا حاجة لإعادة حساب أي شيء يدويًا.

أخطاء شائعة في ng-repeat وكيفية إصلاحها

تنشأ معظم مشاكل ng-repeat من القيم المكررة، أو من وراثة النطاق، أو من وضع التوجيه على العنصر الخطأ. كل عرض من الأعراض المذكورة أدناه يحدد سببه.

  • لا يُسمح بالتكرار في جهاز إعادة الإرسال: تحتوي المجموعة على قيمة متكررة. أضف track by $index، أو أفضل، track by خاصية فريدة.
  • لا تُظهر القائمة أي شيء: الاسم في العرض لا يتطابق مع الخاصية في النطاق. اطبع المجموعة باستخدام {{TopicNames}} للتأكد من وصولها.
  • يتكرر كل عنصر، بما في ذلك الغلاف: تم وضع ng-repeat على الحاوية بدلاً من العنصر. انقله إلى <li> or <tr>.
  • يؤدي تعديل حقل الإدخال إلى تغيير الصف الخطأ: القائمة هي tracتم دفنه بواسطة $index أثناء إعادة ترتيب العناصر. Track بواسطة مُعرّف ثابت بدلاً من ذلك.
  • التغييرات داخل الحلقة لا تستمر: لكل تكرار نطاق فرعي خاص به، لذا فإن الكتابة إلى عنصر أساسي تُنشئ نسخة محلية. اكتب إلى خاصية كائن، مثل item.done.

الأسئلة الشائعة

نعم ، باستخدام ng-repeat="(key, value) in myObject"لاحظ أن AngularJS يقوم بتكرار مفاتيح الكائن بترتيب فرز، وليس بترتيب الإدخال، لذا فإن المصفوفة أكثر أمانًا عندما يكون التسلسل مهمًا.

سلسلة المرشحات في التعبير، كما في ng-repeat="t in TopicNames | filter:search | orderBy:'name'"لم يطرأ أي تغيير على المصفوفة الأصلية؛ فقط الترتيب المعروض والمجموعة الفرعية تتغير.

نعم. AI تقوم الأدوات بربط ng-repeat بـ *ngFor و track by to tracوظائف kBy. تحقق من عوامل التصفية بعناية، لأن Angular أسقطت عمداً عوامل التصفية المدمجة وأنابيب orderBy.

تكتشف أدوات الذكاء الاصطناعي استدعاءات الدوال داخل تعبير التكرار، والتي تُعاد تشغيلها في كل عملية تجزئة، والمفقودة. tracتُعدّ عبارات k by التي تُجبر على إعادة بناء DOM بالكامل من الأسباب الشائعة لبطء القائمة.

استخدم نموذج التعليقات، ng-repeat-start و ng-repeat-end، وهو ما يكرر مجموعة من العناصر الشقيقة. وهذا مهم في الجداول، حيث أن إضافة عنصر div إضافي سيؤدي إلى خلل في بنية الصفحة.

تلخيص هذه التدوينة بـ: