Hiểu biểu thức ngRepeat 'track by'


101

Tôi đang gặp khó khăn trong việc hiểu cách hoạt động của bản nhạc bằng biểu thức ng-repeat trong anglejs. Tài liệu rất khan hiếm: http://docs.angularjs.org/api/ng/directive/ngRepeat

Bạn có thể giải thích những gì là sự khác biệt giữa hai đoạn mã là về liên kết dữ liệu và các khía cạnh khác có liên quan?

với: track by $index

<!--names is an array-->
<div ng-repeat="(key, value) in names track by $index">
  <input ng-model="value[key]">                         
</div>

không có (cùng một đầu ra)

<!--names is an array-->
<div ng-repeat="(key, value) in names">
   <input ng-model="value[key]">                         
</div>

Một câu hỏi hay, với những câu trả lời rất hay! Thật tiếc khi OP đã không chấp nhận một câu trả lời - hoặc bạn không nghĩ rằng câu hỏi đó đã được trả lời đúng?
Mawg nói hãy phục hồi Monica

Bạn đúng! Tôi chỉ chấp nhận câu trả lời của TJ.
Jonathan Grupp

Câu trả lời:


96

Bạn có thể track by $indexnếu nguồn dữ liệu của bạn có số nhận dạng trùng lặp

ví dụ: $scope.dataSource: [{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]

Bạn không thể lặp lại bộ sưu tập này trong khi sử dụng 'id' làm định danh (id trùng lặp: 1).

KHÔNG LÀM VIỆC:

<element ng-repeat="item.id as item.name for item in dataSource">
  // something with item ...
</element>

nhưng bạn có thể, nếu sử dụng track by $index:

<element ng-repeat="item in dataSource track by $index">
  // something with item ...
</element>

1
cảm ơn câu trả lời của bạn! Nhưng chắc chắn các số nhận dạng trùng lặp không phải là trường hợp sử dụng duy nhất. Ngoài ra, tôi muốn biết những gì đang xảy ra 'bí mật'.
Jonathan Grupp,

2
tốt, điều đó thật dễ dàng: chỉ cần nhìn vào , tất cả đều là mã nguồn mở;)
nilsK

4
Câu hỏi này là cũ nhưng tôi vẫn nghĩ rằng sức mạnh này giúp hiểu rõ hơn về nhiều bennadel.com/blog/... phiên bản ngắn của lời giải thích đây docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D

3
Một điều nữa cần lưu ý là nếu bạn có thể sử dụng theo dõi bằng phím, bạn sẽ có được hiệu suất tốt hơn (blog.500tech.com/is-reactjs-fast). Tính năng này cho phép bạn liên kết một đối tượng JavaScript với một nút ngRepeat DOM (Mô hình Đối tượng Tài liệu) bằng cách sử dụng một số nhận dạng duy nhất. Với sự liên kết này, AngularJS sẽ không $ phá hủy và tạo lại các nút DOM một cách không cần thiết. Điều này có thể mang lại hiệu suất và lợi ích trải nghiệm người dùng rất lớn ( bennadel.com/blog/… ).
Braulio

Tôi có một danh sách 700 mặt hàng lẻ. Thời gian kết xuất tăng từ 4 giây lên 100 mili giây. Theo dõi bằng nên được sử dụng cho tất cả các ngRepeat dựa trên dữ liệu được lấy từ phần còn lại.
Patrick

60

một bản tóm tắt ngắn:

track by được sử dụng để liên kết dữ liệu của bạn với quá trình tạo DOM (và chủ yếu là tạo lại) được thực hiện bởi ng-repeat.

khi bạn thêm, track byvề cơ bản, bạn sẽ nói với góc để tạo một phần tử DOM duy nhất cho mỗi đối tượng dữ liệu trong bộ sưu tập đã cho

điều này có thể hữu ích khi phân trang và lọc, hoặc bất kỳ trường hợp nào trong đó các đối tượng được thêm vào hoặc xóa khỏi ng-repeatdanh sách.

thông thường, không có track bygóc cạnh sẽ liên kết các đối tượng DOM với bộ sưu tập bằng cách đưa thuộc tính expando - $$hashKey- vào các đối tượng JavaScript của bạn và sẽ tạo lại nó (và liên kết lại đối tượng DOM) với mọi thay đổi.

giải thích đầy đủ:

http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

một hướng dẫn thực tế hơn:

http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

(theo dõi bằng có sẵn trong góc> 1.2)


8

Nếu bạn đang làm việc với các đối tượng theo dõi bằng mã định danh (ví dụ: $ index) thay vì toàn bộ đối tượng và bạn tải lại dữ liệu của mình sau đó, ngRepeat sẽ không xây dựng lại các phần tử DOM cho các mục mà nó đã hiển thị , ngay cả khi các đối tượng JavaScript trong bộ sưu tập có đã được thay thế cho những cái mới.


bất kỳ tài liệu tham khảo nào chứng minh điều này?
azerafati

có cách nào để buộc hiển thị lại không? hoặc bất kỳ công việc nào khác xung quanh? Tôi không tìm thấy điều này được đề cập ở bất cứ đâu nhưng tôi tin rằng đây là điều tạo ra một mớ hỗn độn cho tôi và tôi đã lãng phí rất nhiều thời gian.
NeverGiveUp161

1
hoặc không sử dụng theo dõi hoặc thay đổi số nhận dạng duy nhất khi thay đổi đối tượng. Lưu ý bạn không thể thay đổi $ index, đề nghị của mình không sử dụng $ index thay vì sử dụng định danh duy nhất cho đối tượng (ví dụ id)
ram1993
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.