Bằng cách kiểm tra bẩn $scope
đối tượng
Angular duy trì một đơn giản array
của người theo dõi trong các $scope
đối tượng. Nếu bạn kiểm tra bất kỳ $scope
bạn sẽ thấy rằng nó có chứa một cuộc array
gọi $$watchers
.
Mỗi người theo dõi là một trong object
đó có những thứ khác
- Một biểu hiện mà người theo dõi đang theo dõi. Đây có thể chỉ là một
attribute
cái tên, hoặc một cái gì đó phức tạp hơn.
- Một giá trị được biết đến cuối cùng của biểu thức. Điều này có thể được kiểm tra đối với giá trị tính toán hiện tại của biểu thức. Nếu các giá trị khác nhau, trình theo dõi sẽ kích hoạt chức năng và đánh dấu
$scope
là bẩn.
- Một chức năng sẽ được thực hiện nếu người theo dõi bị bẩn.
Người theo dõi được định nghĩa như thế nào
Có nhiều cách khác nhau để định nghĩa một người theo dõi trong AngularJS.
Bạn có thể rõ ràng $watch
một attribute
trên $scope
.
$scope.$watch('person.username', validateUnique);
Bạn có thể đặt một {{}}
phép nội suy trong mẫu của bạn (một trình theo dõi sẽ được tạo cho bạn trên hiện tại $scope
).
<p>username: {{person.username}}</p>
Bạn có thể yêu cầu một chỉ thị như ng-model
xác định người theo dõi cho bạn.
<input ng-model="person.username" />
Các $digest
chu kỳ kiểm tra tất cả sát chống lại giá trị cuối cùng của họ
Khi chúng ta tương tác với AngularJS thông qua các kênh thông thường (ng-model, ng-repeat, v.v.), một chu trình tiêu hóa sẽ được kích hoạt bởi lệnh.
Một chu trình tiêu hóa là một giao dịch sâu đầu tiên $scope
và tất cả các con của nó . Đối với mỗi $scope
object
, chúng tôi lặp lại qua nó $$watchers
array
và đánh giá tất cả các biểu thức. Nếu giá trị biểu thức mới khác với giá trị đã biết cuối cùng, chức năng của trình xem sẽ được gọi. Hàm này có thể biên dịch lại một phần của DOM, tính toán lại một giá trị trên $scope
, kích hoạt một AJAX
request
, bất cứ điều gì bạn cần nó để làm.
Mọi phạm vi đều đi qua và mọi biểu thức đồng hồ được đánh giá và kiểm tra so với giá trị cuối cùng.
Nếu một người theo dõi được kích hoạt, $scope
là bẩn
Nếu một người theo dõi được kích hoạt, ứng dụng sẽ biết có gì đó đã thay đổi và $scope
được đánh dấu là bẩn.
Các chức năng của người theo dõi có thể thay đổi các thuộc tính khác trên $scope
hoặc trên cha mẹ $scope
. Nếu một $watcher
chức năng đã được kích hoạt, chúng tôi không thể đảm bảo rằng các chức năng khác của chúng tôi $scope
vẫn sạch và vì vậy chúng tôi thực hiện lại toàn bộ chu trình phân loại.
Điều này là do AngularJS có ràng buộc hai chiều, do đó dữ liệu có thể được truyền ngược lên $scope
cây. Chúng tôi có thể thay đổi một giá trị ở mức cao hơn $scope
đã được tiêu hóa. Có lẽ chúng ta thay đổi một giá trị trên $rootScope
.
Nếu $digest
bẩn, chúng tôi thực hiện lại toàn bộ $digest
chu trình
Chúng tôi liên tục lặp qua $digest
chu trình cho đến khi chu trình tiêu hóa hoàn toàn sạch (tất cả các $watch
biểu thức có cùng giá trị như trong chu kỳ trước) hoặc chúng tôi đạt đến giới hạn tiêu hóa. Theo mặc định, giới hạn này được đặt ở mức 10.
Nếu chúng tôi đạt đến giới hạn tiêu hóa, AngularJS sẽ phát sinh lỗi trong bảng điều khiển:
10 $digest() iterations reached. Aborting!
Thông báo khó về máy nhưng dễ với nhà phát triển
Như bạn có thể thấy, mỗi khi có gì đó thay đổi trong ứng dụng AngularJS, AngularJS sẽ kiểm tra từng người theo dõi trong $scope
hệ thống phân cấp để xem cách phản hồi. Đối với một nhà phát triển, đây là một lợi ích lớn về năng suất, vì bây giờ bạn cần phải viết gần như không có mã nối dây, AngularJS sẽ chỉ thông báo nếu một giá trị đã thay đổi và làm cho phần còn lại của ứng dụng phù hợp với thay đổi.
Từ quan điểm của máy mặc dù điều này rất kém hiệu quả và sẽ làm chậm ứng dụng của chúng tôi nếu chúng tôi tạo quá nhiều người theo dõi. Misko đã trích dẫn một con số khoảng 4000 người theo dõi trước khi ứng dụng của bạn cảm thấy chậm trên các trình duyệt cũ hơn.
Giới hạn này là dễ dàng để đạt được nếu bạn ng-repeat
vượt quá lớn JSON
array
chẳng hạn. Bạn có thể giảm thiểu việc này bằng các tính năng như ràng buộc một lần để biên dịch mẫu mà không cần tạo trình theo dõi.
Làm thế nào để tránh tạo quá nhiều người theo dõi
Mỗi lần người dùng của bạn tương tác với ứng dụng của bạn, mỗi người theo dõi trong ứng dụng của bạn sẽ được đánh giá ít nhất một lần. Một phần lớn của việc tối ưu hóa ứng dụng AngularJS là giảm số lượng người theo dõi trong $scope
cây của bạn . Một cách dễ dàng để làm điều này là với một lần ràng buộc .
Nếu bạn có dữ liệu hiếm khi thay đổi, bạn chỉ có thể liên kết dữ liệu đó một lần bằng cách sử dụng cú pháp :: như vậy:
<p>{{::person.username}}</p>
hoặc là
<p ng-bind="::person.username"></p>
Liên kết sẽ chỉ được kích hoạt khi mẫu chứa được hiển thị và dữ liệu được tải vào $scope
.
Điều này đặc biệt quan trọng khi bạn có một ng-repeat
với nhiều mặt hàng.
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>