AngularJS ng-ทำซ้ำคำสั่งพร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

คำสั่ง `ng-repeat` ใน AngularJS จะสร้างสำเนาขององค์ประกอบหนึ่งรายการสำหรับแต่ละรายการในคอลเลกชันที่กำหนดไว้ในขอบเขตของคอนโทรลเลอร์ มันจะแปลงอาร์เรย์ให้เป็นรายการ ตาราง หรือมาร์กอัปที่ทำซ้ำใดๆ โดยไม่ต้องเขียนลูปด้วยตนเอง

  • 🔁 พฤติกรรมหลัก: ng-repeat จะคัดลอกองค์ประกอบหลักหนึ่งครั้งต่อรายการ ดังนั้นคำสั่งนี้จึงควรอยู่บนองค์ประกอบที่ต้องการทำซ้ำ ไม่ใช่บนคอนเทนเนอร์ของมัน
  • 🏷️ ตัวแปรลูป: ชื่อที่อยู่หน้าคำว่า "in" จะกลายเป็นชื่อเรียกแทนเฉพาะที่สำหรับรายการปัจจุบันภายในสำเนาที่สร้างขึ้นนั้น
  • 🧬 ขอบเขตสำหรับเด็ก: แต่ละรอบการวนซ้ำจะได้รับขอบเขตย่อยของตัวเอง ซึ่งเป็นเหตุผลว่าทำไมการกำหนดค่าพื้นฐานภายในลูปจึงไม่ส่งผลต่อขอบเขตหลัก
  • 🔑 เอกลักษณ์ Tracking: A track by expression จะบอก AngularJS ว่าจะระบุรายการต่างๆ ได้อย่างไร และจำเป็นต้องใช้เมื่อคอลเลกชันมีค่าซ้ำกัน
  • 🔢 ตำแหน่งที่ตั้งในตัว: คุณสมบัติ เช่น $index, $first และ $last สามารถใช้งานได้ภายในแต่ละรอบการวนซ้ำ เพื่อใช้ในการกำหนดหมายเลขและจัดรูปแบบ
  • ⚠️ สถานะการสนับสนุน: AngularJS สิ้นสุดการสนับสนุนเมื่อวันที่ 31 ธันวาคม 2021 และจะไม่ได้รับการแก้ไขช่องโหว่ด้านความปลอดภัยอีกต่อไป

คำสั่ง ng-repeat ของ AngularJS

คำสั่ง ng-repeat ใน AngularJS

การขอ ng-ซ้ำ คำสั่ง ใน AngularJS นั้น `ng-repeat` ใช้สำหรับแสดงค่าที่ซ้ำกันซึ่งกำหนดไว้ในคอนโทรลเลอร์ บางครั้งเราจำเป็นต้องแสดงรายการหลายรายการในวิว และ `ng-repeat` จะแสดงรายการที่กำหนดไว้ในคอนโทรลเลอร์ลงบนหน้าเว็บ

⚠️ ประกาศเกี่ยวกับการสนับสนุน: AngularJS มาถึงแล้ว สิ้นสุดชีวิตเมื่อวันที่ 31 ธันวาคม 2021 และจะไม่ได้รับการแก้ไขเพิ่มเติมหรือการแก้ไขด้านความปลอดภัยอีกต่อไป คำสั่งด้านล่างนี้ยังคงถูกต้องสำหรับการบำรุงรักษาแอปพลิเคชัน AngularJS 1.x ที่มีอยู่ ในระบบสมัยใหม่ เชิงมุม สิ่งที่เทียบเท่าคือ *ngFor คำสั่งเชิงโครงสร้าง

ตัวอย่างคำสั่ง AngularJS ng-repeat

เรามาดูตัวอย่างการใช้งาน directive 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. ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร ตัวควบคุมก่อนอื่น เราจะกำหนดอาร์เรย์ของรายการที่จะแสดงในมุมมอง ในที่นี้คืออาร์เรย์ที่ชื่อว่า 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 โดย with ng-repeat

ข้อผิดพลาดที่พบบ่อยที่สุดของ ng-repeat คือข้อผิดพลาดนี้ Duplicates in a repeater are not allowedข้อผิดพลาดนี้จะปรากฏขึ้นเมื่อชุดข้อมูลมีค่าเดียวกันซ้ำกันสองครั้ง และจะทำให้การแสดงผลรายการหยุดลงโดยสิ้นเชิง

สาเหตุคืออัตลักษณ์ tracAngularJS ต้องการคีย์ที่เสถียรสำหรับแต่ละรายการ เพื่อให้สามารถนำโหนด DOM กลับมาใช้ซ้ำได้ แทนที่จะสร้างใหม่ทุกครั้งที่มีการประมวลผลข้อมูล โดยค่าเริ่มต้นจะใช้ค่าของรายการเอง ดังนั้นค่าที่เหมือนกันสองค่าจึงเกิดการชนกัน

<!-- 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>

<!-- Best 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-class สำหรับลายม้าลายpingเช่นเดียวกับใน ng-class="{'row-alt': $odd}"หรือใช้ ng-if เพื่อแสดงตัวคั่นในทุกแถวยกเว้นแถวสุดท้าย ng-if="!$last"การแสดงหมายเลขแถวที่อ่านง่ายนั้นทำได้ง่ายๆ {{$index + 1}}เนื่องจากดัชนีเริ่มต้นที่ศูนย์ คุณสมบัติทั้งหกจะถูกคำนวณใหม่โดยอัตโนมัติทุกครั้งที่คอลเลกชันเปลี่ยนแปลง ดังนั้นจึงไม่จำเป็นต้องคำนวณอะไรใหม่ด้วยตนเอง

ข้อผิดพลาดทั่วไปของ ng-repeat และวิธีแก้ไข

ปัญหาส่วนใหญ่ที่เกี่ยวกับ ng-repeat เกิดจากค่าซ้ำกัน การสืบทอดขอบเขต หรือการวาง directive ไว้บนองค์ประกอบที่ไม่ถูกต้อง อาการแต่ละอย่างด้านล่างจะระบุสาเหตุของมัน

  • ไม่อนุญาตให้มีข้อมูลซ้ำกันในรีพีเตอร์: คอลเลกชันนี้มีค่าซ้ำกัน เพิ่ม track by $indexหรือจะให้ดีกว่านั้น track by อสังหาริมทรัพย์ที่มีเอกลักษณ์เฉพาะตัว
  • รายการดังกล่าวไม่แสดงผลอะไรเลย: ชื่อในมุมมองไม่ตรงกับคุณสมบัติในขอบเขต พิมพ์คอลเลกชันด้วย {{TopicNames}} เพื่อยืนยันว่าสินค้ามาถึงแล้ว
  • ทุกองค์ประกอบมีการซ้ำกัน รวมถึงส่วนห่อหุ้มด้วย: ng-repeat ถูกวางไว้บนคอนเทนเนอร์แทนที่จะอยู่บนไอเทม ย้ายไปไว้ที่อื่นเถอะ <li> or <tr>.
  • การแก้ไขข้อมูลป้อนเข้ากลับไปแก้ไขแถวที่ไม่ถูกต้อง: รายชื่อคือ tracโดนโดย $index ในระหว่างที่สินค้ากำลังจัดเรียงใหม่ Tracใช้ k ด้วยตัวระบุที่เสถียรแทน
  • การเปลี่ยนแปลงภายในลูปจะไม่คงอยู่: แต่ละรอบการทำงานจะมีขอบเขตย่อยของตัวเอง ดังนั้นการเขียนไปยังค่าพื้นฐานจะสร้างสำเนาเฉพาะที่ การเขียนไปยังคุณสมบัติของวัตถุ เช่น item.done.

คำถามที่พบบ่อย

ใช่ ใช้ ng-repeat="(key, value) in myObject"โปรดทราบว่า AngularJS จะวนซ้ำคีย์ของอ็อบเจ็กต์ตามลำดับที่เรียงแล้ว ไม่ใช่ตามลำดับการแทรก ดังนั้นการใช้อาร์เรย์จึงปลอดภัยกว่าเมื่อลำดับมีความสำคัญ

ใช้ตัวกรองแบบลูกโซ่ในนิพจน์ ดังนี้ ng-repeat="t in TopicNames | filter:search | orderBy:'name'"อาร์เรย์ต้นฉบับยังคงเหมือนเดิม มีเพียงลำดับการแสดงผลและชุดย่อยเท่านั้นที่เปลี่ยนแปลงไป

ใช่. AI เครื่องมือแมป ng-repeat ไปยัง *ngFor และ track โดยถึง tracฟังก์ชัน kBy โปรดตรวจสอบตัวกรองอย่างละเอียด เนื่องจาก Angular จงใจตัดฟังก์ชัน filter และ orderBy ที่มีมาให้ในตัวออกไป

เครื่องมือ AI ตรวจจับการเรียกใช้ฟังก์ชันภายในนิพจน์การทำซ้ำ ซึ่งจะทำงานซ้ำทุกครั้งที่มีการประมวลผลข้อมูล และส่วนที่ขาดหายไป track โดยใช้ข้อกำหนดที่บังคับให้สร้าง DOM ใหม่ทั้งหมด ซึ่งทั้งสองอย่างนี้เป็นสาเหตุหลักที่ทำให้รายการทำงานช้า

โปรดใช้แบบฟอร์มแสดงความคิดเห็น ng-repeat-start และ ng-repeat-endซึ่งเป็นการทำซ้ำองค์ประกอบพี่น้องหลายๆ ตัว เรื่องนี้สำคัญในตาราง เพราะถ้ามี div เพิ่มเข้ามาจะทำให้โครงสร้าง HTML เสียหาย

สรุปโพสต์นี้ด้วย: