2017-03-23 18 views
14

Giả sử tôi có một function noificationHandler() trong dịch vụ của tôi.ts nằm ngoài ngữ cảnh của góc cạnh. noificationHandler() được gọi bởi bên thứ ba và noificationHandler() về cơ bản tiêu thụ một mảng và phát ra mảng cho các thành phần đã đăng ký dịch vụ của mình.Angular2 zone.run() vs ChangeDetectorRef.detectChanges()

service.ts

public mySubject: Subject<any> = new Subject(); 
    public myObservable = this.mySubject.asObservable(); 

    constructor() { 
     this.registry.subscribe("notification.msg",this.noificationHandler.bind(this)); 
    } 

    noificationHandler(data) { 
     this.publishUpdate(data) 
    } 

    publishUpdate(data) { 
     this.mySubject.next(data); 
    } 

component.ts

constructor(private service: myService) { 
    this.service.myObservable.subscribe(list => { 
     this.list = list; 
    }); 
} 

^^^ vào thời điểm này các mẫu không được cập nhật với các dữ liệu mới

Kể từ khi "notification.msg" nằm ngoài khu vực của góc, góc cạnh s ch phát hiện ange không được chạy khi sự kiện này ("notification.msg") được gọi.

Bây giờ có 2 cách để gọi phát hiện thay đổi.

1) Bằng cách gói các noificationHandler() bên trong zone.run góc của()

this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this))); 

2) Bằng cách cá nhân yêu cầu thành phần để phát hiện những thay đổi

constructor(private service: myService, private ref: ChangeDetectorRef) { 
    this.service.myObservable.subscribe(list => { 
     this.list = list; 
     this.ref.detectChanges(); // <==== manually invoking change detection 
    }); 
} 

Cả hai tùy chọn làm việc! Và cấu trúc thành phần của tôi là như sau

A --> root component 
B 
C 
D // my component is here (4 levels of nesting) 

Câu hỏi -

1) Sẽ detectChanges() phát hiện những thay đổi duy nhất cho các thành phần riêng của mình hoặc sẽ nó cũng chạy phát hiện sự thay đổi về thành phần con?

2) sẽ zone.run() kích hoạt phát hiện thay đổi của tất cả các thành phần từ gốc đến lá?

Trong số các zone.run() và detectChanges() Tôi tò mò muốn làm gì tốt hơn trong hiệu suất ?

Trả lời

3

Cả hai đều hoàn toàn khác nhau.

NgZone là một thư viện cung cấp các vùng cho ứng dụng của bạn để bạn có thể chạy các phiên bản thành nhiều phạm vi.

ChangeDetection luôn từ cha mẹ sang lá như A> B> C Khi bạn gọi detectChanges(), nó sẽ gọi thành phần hiện tại và các thành phần con của nó. Vì vậy, đây là cách tiếp cận tốt nhất để sử dụng OnPush changesdetectionChiến lược cho các thành phần lá, do đó, chúng sẽ chỉ phát hiệnThay đổi khi đầu vào được cập nhật.

Ngoài ra, ApplicationRef cũng tương tự như ChangeDetector; sự khác biệt là nó sẽ phát hiện những thay đổi từ thành phần gốc đến thành phần con cuối cùng.

ChaneDetection và NgZone là sự kết hợp tốt nhất luôn để tránh ChangeDetection không cần thiết

16

ApplicationRef.tick (giống như setTimeout()), và zone.run() phát hiện sự thay đổi gây ra trên toàn bộ ứng dụng. Cũng nghe sự kiện bổ sung trong góc hoặc bằng góc (sử dụng xem các ràng buộc hoặc @HostBinding() nguyên nhân thay đổi detectionf cho toàn bộ ứng dụng.

ChangeDetectorRef.detectChanges chạy thay đổi phát hiện cho một thành phần cụ thể (và con cháu của mình nếu áp dụng, ví dụ vì bindings đầu vào)

Nếu một số mã chạy bên ngoài Angulars khu gọi vào Angulars mã và thay đổi trạng thái, sau đó thay đổi phát hiện cần phải được gọi explicitely vì góc không có cách nào để biết rằng nhà nước thay đổi.

Nếu sự thay đổi đối với nhà nước là cục bộ cho một thành phần (ví dụ: trường thành phần), ChangeDetectorRef.detectChanges hoặc ChangeDetectorRef.markforCheck hiệu quả hơn. Nếu cuộc gọi từ bên ngoài ví dụ điều hướng đến một tuyến đường khác, điều này có thể gây hậu quả cho một số thành phần và cũng không rõ ràng khi toàn bộ thay đổi tuyến đường được hoàn thành vì nó có thể gây ra cuộc gọi không đồng bộ (và gọi lại gọi lại). Trong trường hợp này, zone.run() là tùy chọn tốt hơn, vì mã gọi trực tiếp và gián tiếp (như callbacks of observables và promise) được gọi sẽ chạy bên trong Angulars zone và Angular sẽ nhận ra chúng và gọi tự động phát hiện thay đổi.