2016-01-26 19 views
8

Hôm nay tôi đã phải sửa chữa một vấn đề hiệu suất gây ra bởi mã này: sự chú ý Pay để updateStats gọi bên trong mẫuChức năng bên trong một mẫu được gọi là nhiều lần (góc JS)

<script type="text/ng-template" id="entityGrouper"> 

<section> 

<div> 
<ul ng-click="hideEntityBox = !hideEntityBox"> 
<li> 
{{ entityNode.name }} 
</li> 
<li ng-repeat="breadcrumbItem in entityNode.breadcrumb"> 
{{ breadcrumbItem }} 
</li> 
</ul> 
{{ updateStats(entityNode) }} 
<span ng-include="'/mypath/views/resume.html'"></span> 
</div> 

<div> 

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div> 
<div ng-repeat="entity in entityNode.group" ng-include="'entityBox'"></div> 

</section> 

</script> 

Template sử dụng:

Sau khi gỡ lỗi mã này, tôi phát hiện ra rằng hàm này được gọi nhiều lần hơn kích thước mảng (mảng của tôi có 4 đối tượng và hàm được gọi nhiều hơn 100 lần), thậm chí di chuột được gọi là hàm này. Tôi đã sửa lỗi đó bằng cách chỉ cần đặt một ng-init bên trong khuôn mẫu và bây giờ nó hoạt động đúng cách, nhưng tôi đã không tìm ra lý do tại sao chức năng này được gọi nhiều lần. Có điều gì đó về hai chiều ràng buộc dữ liệu?

+0

Bạn có gọi đệ quy cùng một mẫu không? có một lần nữa một cuộc gọi '

' được thực hiện bên trong mẫu – Developer

Trả lời

1

này đang xảy ra không phải vì hai chiều dữ liệu ràng buộc (nó được áp dụng để tạo thành đầu vào), nhưng thay vì góc phát hiện sự thay đổi. Angular định kỳ kiểm tra xem có bất kỳ giá trị nào, ràng buộc với một khuôn mẫu, thay đổi, và nếu có - cập nhật giá trị của nó trong khung nhìn. Thông thường, nó được kích hoạt bởi sự kiện do người dùng tạo. Để kiểm tra xem giá trị của updateStats(entityNode) có thay đổi hay không, Angular đánh giá nó, gây ra hiệu suất.

Để khắc phục điều này, bạn có thể sử dụng liên kết một lần được đề cập updateStats(entityNode)nếu kết quả được đặt một lần và sẽ không bao giờ thay đổi trong tương lai. Tôi đoán, đây là trường hợp của bạn và bạn đã chuyển đánh giá sang ng-init. Đối với các giá trị cập nhật theo thời gian, sẽ tốt hơn nếu bạn tạo một thuộc tính riêng trong entityNode như entityNode.stats, hiển thị nó trong mẫu và chạy updateStats(entityNode) trong bộ điều khiển hoặc dịch vụ của bạn chỉ khi cần thiết. Bằng cách đó, bạn sẽ ngăn chặn chạy updateStats(entityNode) trên mỗi chu kỳ phân hủy (bạn đã thấy tần suất đó) và do đó cải thiện hiệu suất của ứng dụng của bạn.

4

Bạn nên sử dụng $watch cho các trường hợp như thế này. Vì bạn đang ràng buộc một hàm {{updateStats()}}, nó sẽ thực hiện trên mọi chu kỳ tiêu hóa.

Vì vậy, trong mã của bạn bất cứ khi nào một chu kỳ tiêu hóa được gọi, nó cũng sẽ gọi hàm. Và các chu kỳ tiêu hóa thường được gọi nội bộ trong Angular.

+0

này phải là câu trả lời đúng được chấp nhận – thiagoh

2

Những gì bạn thấy là kết quả của chu trình phân hủy.

Thêm :: sẽ gọi hàm một lần/liên kết một lần.

{{ ::updateStats(entityNode) }}

+0

những gì :: chính xác làm gì? –

+1

'::' cung cấp một ràng buộc thời gian. Nếu bạn tiền tố một biểu thức với điều này, nó sẽ ngừng chạy hoặc tính toán lại sau lần phân tích đầu tiên. Thông tin thêm * Phần ràng buộc một lần * của [tài liệu] (https://docs.angularjs.org/guide/expression). –

Các vấn đề liên quan