Câu trả lời ngắn gọn : bạn thực sự cần chức năng như vậy hay bạn có thể sử dụng tài sản? http://jsfiddle.net/awnqm/1/
Câu trả lời dài
Để đơn giản, tôi sẽ chỉ mô tả trường hợp của bạn - ngRepeat cho mảng đối tượng. Ngoài ra, tôi sẽ bỏ qua một số chi tiết.
AngularJS sử dụng kiểm tra bẩn để phát hiện các thay đổi. Khi ứng dụng được bắt đầu nó chạy $digest
cho $rootScope
. $digest
sẽ thực hiện chuyển tải theo chiều sâu cho hệ thống phân cấp của phạm vi . Tất cả các phạm vi đều có danh sách đồng hồ. Mỗi đồng hồ có giá trị cuối cùng (ban đầu initWatchVal
). Đối với mỗi phạm vi cho tất cả các đồng hồ $digest
chạy nó, nhận giá trị hiện tại ( watch.get(scope)
) và so sánh với watch.last
. Nếu giá trị hiện tại không bằng watch.last
(luôn cho lần so sánh đầu tiên) $digest
đặt dirty
thành true
. Khi tất cả các phạm vi được xử lý nếu dirty == true
$digest
bắt đầu một chuyển tải theo chiều sâu khác từ đó $rootScope
. $digest
kết thúc khi dơ bẩn == false hoặc số lượng truyền qua == 10. Trong trường hợp thứ hai, lỗi "đã đạt đến 10 lần lặp lại hàm tiêu hóa ()." sẽ được ghi lại.
Bây giờ về ngRepeat
. Đối với mỗi watch.get
lệnh gọi, nó lưu trữ các đối tượng từ bộ sưu tập (giá trị trả về của getEntities
) với thông tin bổ sung trong bộ nhớ cache ( HashQueueMap
bằng hashKey
). Đối với mọi watch.get
cuộc gọi ngRepeat
cố gắng lấy đối tượng của nó hashKey
từ bộ nhớ cache. Nếu nó không tồn tại trong bộ nhớ cache, ngRepeat
lưu trữ nó trong bộ nhớ cache, tạo ra phạm vi mới, puts đối tượng vào nó, tạo ra phần tử DOM, vv .
Bây giờ về hashKey
. Thường hashKey
là số duy nhất được tạo bởi nextUid()
. Nhưng nó có thể hoạt động . hashKey
được lưu trữ trong đối tượng sau khi tạo để sử dụng trong tương lai.
Tại sao ví dụ của bạn tạo ra lỗi : hàm getEntities()
luôn trả về mảng với đối tượng mới. Đối tượng này không có hashKey
và không tồn tại trong ngRepeat
bộ nhớ cache. Vì vậy, ngRepeat
trên mỗi lần watch.get
tạo phạm vi mới cho nó với đồng hồ mới cho {{entity.id}}
. Đồng hồ này đầu tiên watch.get
có watch.last == initWatchVal
. Vì vậy watch.get() != watch.last
. Vì vậy, $digest
bắt đầu hành trình mới. Vì vậy, hãy ngRepeat
tạo phạm vi mới với đồng hồ mới. Vì vậy, ... sau 10 lần duyệt bạn sẽ gặp lỗi.
Làm thế nào bạn có thể sửa chữa nó
- Không tạo đối tượng mới trong mỗi
getEntities()
cuộc gọi.
- Nếu bạn cần tạo các đối tượng mới, bạn có thể thêm
hashKey
phương thức cho chúng. Xem chủ đề này để biết ví dụ.
Hy vọng những người biết AngularJS nội bộ sẽ sửa cho tôi nếu tôi sai ở một số điểm.