Từ tài liệu:
DetChanges (): void
Kiểm tra các máy dò thay đổi và con của nó.
Điều đó có nghĩa là, nếu có trường hợp bất kỳ điều gì trong mô hình của bạn (lớp của bạn) đã thay đổi nhưng nó không phản ánh chế độ xem, bạn có thể cần thông báo cho Angular để phát hiện những thay đổi đó (phát hiện các thay đổi cục bộ) và cập nhật chế độ xem.
Các tình huống có thể xảy ra có thể là:
1- Bộ phát hiện thay đổi được tách ra khỏi chế độ xem (xem phần tách ra )
2- Một bản cập nhật đã xảy ra nhưng nó không nằm trong Khu vực góc, do đó, Angular không biết về nó.
Giống như khi chức năng của bên thứ ba đã cập nhật mô hình của bạn và bạn muốn cập nhật chế độ xem sau đó.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Vì mã này nằm ngoài vùng của Angular (có thể), nên rất có thể bạn cần đảm bảo phát hiện các thay đổi và cập nhật chế độ xem, do đó:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
LƯU Ý :
Có nhiều cách khác để thực hiện công việc trên, nói cách khác, có những cách khác để mang lại sự thay đổi đó trong chu kỳ thay đổi Angular.
** Bạn có thể bao bọc chức năng của bên thứ ba bên trong một khu vực.
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** Bạn có thể gói chức năng bên trong setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- Cũng có trường hợp bạn cập nhật mô hình sau khi change detection cycle
kết thúc, trong trường hợp đó bạn gặp phải lỗi đáng sợ này:
"Biểu hiện đã thay đổi sau khi được kiểm tra";
Điều này thường có nghĩa là (từ ngôn ngữ Angular2):
Tôi đã thấy một sự thay đổi trong mô hình của bạn do một trong những cách được chấp nhận của tôi (sự kiện, yêu cầu XHR, setTimeout và ...) và sau đó tôi đã chạy phát hiện thay đổi của mình để cập nhật chế độ xem của bạn và tôi đã hoàn thành nó, nhưng sau đó có một cách khác Chức năng trong mã của bạn đã cập nhật lại mô hình và tôi không muốn chạy lại phát hiện thay đổi của mình vì không còn kiểm tra bẩn như AngularJS nữa: D và chúng ta nên sử dụng luồng dữ liệu một chiều!
Bạn chắc chắn sẽ gặp phải lỗi này: P.
Một số cách để khắc phục nó:
1- Cách thích hợp : đảm bảo rằng bản cập nhật nằm trong chu kỳ phát hiện thay đổi (Cập nhật Angular2 là luồng một chiều xảy ra một lần, không cập nhật mô hình sau đó và di chuyển mã của bạn đến nơi / thời gian tốt hơn).
2- Cách lười biếng : chạy DetChanges () sau bản cập nhật đó để làm cho angular2 hài lòng, đây chắc chắn không phải là cách tốt nhất, nhưng khi bạn hỏi các tình huống có thể xảy ra, đây là một trong số chúng.
Theo cách này bạn đang nói: Tôi chân thành biết bạn đã chạy phát hiện thay đổi, nhưng tôi muốn bạn làm lại vì tôi phải cập nhật một cái gì đó ngay sau khi bạn hoàn thành việc kiểm tra.
3- Đặt mã bên trong a setTimeout
, vì setTimeout
được vá theo vùng và sẽ chạy detectChanges
sau khi hoàn thành.
Từ các tài liệu
markForCheck() : void
Đánh dấu tất cả các tổ tiên ChangeDetectionStrargety sẽ được kiểm tra.
Điều này chủ yếu là cần thiết khi ChangeDetectionStrargety của thành phần của bạn là OnPush .
OnPush có nghĩa là, chỉ chạy phát hiện thay đổi nếu bất kỳ điều nào trong số này đã xảy ra:
1- Một trong những @input của thành phần đã được thay thế hoàn toàn bằng một giá trị mới, hoặc đơn giản là, nếu tham chiếu của thuộc tính @Input đã thay đổi hoàn toàn.
Vì vậy, nếu ChangeDetectionStrargety của thành phần của bạn là OnPush và sau đó bạn có:
var obj = {
name:'Milad'
};
Và sau đó bạn cập nhật / biến đổi nó như sau:
obj.name = "a new name";
Điều này sẽ không cập nhật tham chiếu obj , do đó phát hiện thay đổi sẽ không chạy, do đó chế độ xem không phản ánh cập nhật / đột biến.
Trong trường hợp này, bạn phải thông báo thủ công cho Angular để kiểm tra và cập nhật chế độ xem (markForCheck);
Vì vậy, nếu bạn đã làm điều này:
obj.name = "a new name";
Bạn cần phải làm điều này:
this.cd.markForCheck();
Thay vào đó, bên dưới sẽ khiến phát hiện thay đổi chạy:
obj = {
name:"a new name"
};
Mà thay thế hoàn toàn obj trước bằng một cái mới {}
;
2- Một sự kiện đã được kích hoạt, như một cú nhấp chuột hoặc một cái gì đó tương tự hoặc bất kỳ thành phần con nào đã phát ra một sự kiện.
Các sự kiện như:
- Nhấp chuột
- Keyup
- Sự kiện đăng ký
- Vân vân.
Vì vậy, trong ngắn hạn:
Sử dụng detectChanges()
khi bạn đã cập nhật mô hình sau khi góc đã chạy phát hiện thay đổi hoặc nếu bản cập nhật hoàn toàn không ở trong thế giới góc cạnh.
Sử dụng markForCheck()
nếu bạn đang sử dụng OnPush và bạn đang bỏ qua ChangeDetectionStrategy
bằng cách thay đổi một số dữ liệu hoặc bạn đã cập nhật mô hình bên trong setTimeout ;