Đầu tiên, lưu ý rằng ngoại lệ này sẽ chỉ được ném khi bạn đang chạy ứng dụng của mình ở chế độ dev (theo mặc định là beta-0): Nếu bạn gọi enableProdMode()
khi bootstrapping ứng dụng, nó sẽ không bị ném ( xem cập nhật đầy đủ ).
Thứ hai, đừng làm điều đó bởi vì ngoại lệ này bị ném vì lý do chính đáng: Tóm lại, khi ở chế độ dev, mọi vòng phát hiện thay đổi được theo dõi ngay sau vòng thứ hai để xác minh không có ràng buộc nào thay đổi kể từ khi kết thúc vòng đầu tiên, vì điều này sẽ chỉ ra rằng những thay đổi đang được gây ra bởi chính phát hiện thay đổi.
Trong phần mở rộng của bạn, ràng buộc {{message}}
được thay đổi bởi lệnh gọi của bạn setMessage()
, xảy ra trong ngAfterViewInit
hook, xảy ra như một phần của lượt phát hiện thay đổi ban đầu. Mặc dù bản thân nó không có vấn đề gì - vấn đề là setMessage()
thay đổi liên kết nhưng không kích hoạt vòng phát hiện thay đổi mới, nghĩa là thay đổi này sẽ không được phát hiện cho đến khi một vòng phát hiện thay đổi trong tương lai được kích hoạt ở một nơi khác.
Việc thực hiện: Bất cứ điều gì thay đổi ràng buộc đều cần để kích hoạt vòng phát hiện thay đổi khi thực hiện.
Cập nhật để đáp ứng với tất cả các yêu cầu cho một ví dụ về cách thực hiện điều đó : Giải pháp của @ Tycho hoạt động, cũng như ba phương pháp trong câu trả lời @MarkRajcok đã chỉ ra. Nhưng thành thật mà nói, tất cả họ đều cảm thấy xấu xí và sai đối với tôi, giống như kiểu hack mà chúng ta đã quen với việc dựa vào ng1.
Để chắc chắn, thỉnh thoảng có trường hợp hack này là phù hợp, nhưng nếu bạn đang sử dụng chúng trên bất cứ điều gì ngoài một cơ sở rất thường xuyên, đó là một dấu hiệu cho thấy bạn đang chiến đấu với khuôn khổ thay vì chấp nhận hoàn toàn bản chất phản ứng của nó.
IMHO, một cách thành ngữ hơn, "cách Angular2" để tiếp cận điều này là một cái gì đó dọc theo dòng: ( plunk )
@Component({
selector: 'my-app',
template: `<div>I'm {{message | async}} </div>`
})
export class App {
message:Subject<string> = new BehaviorSubject('loading :(');
ngAfterViewInit() {
this.message.next('all done loading :)')
}
}
ExpressionChangedAfterItHasBeenCheckedError
lỗi đều giải thích hành vi rất chi tiết.