ก่อนอื่นโปรดทราบว่าข้อยกเว้นนี้จะถูกโยนทิ้งเมื่อคุณเรียกใช้แอปของคุณในโหมด dev (ซึ่งเป็นกรณีโดยค่าเริ่มต้นเป็น beta-0): หากคุณโทรenableProdMode()
เมื่อทำการบู๊ตแอปมันจะไม่ถูกโยน ( ดู อัปเดตเสียงแตก )
ประการที่สองอย่าทำเช่นนั้นเพราะมีการโยนข้อยกเว้นนี้ด้วยเหตุผลที่ดี: ในระยะสั้นเมื่ออยู่ในโหมด dev การตรวจจับการเปลี่ยนแปลงทุกรอบจะตามมาทันทีในรอบที่สองที่ตรวจสอบว่าไม่มีการเปลี่ยนแปลงใด ๆ หลังจากสิ้นสุดรอบแรก เช่นนี้จะแสดงว่ามีการเปลี่ยนแปลงเกิดจากการตรวจจับการเปลี่ยนแปลงตัวเอง
ในเสียงแตกของคุณการผูก{{message}}
จะเปลี่ยนไปตามการเรียกของคุณsetMessage()
ซึ่งเกิดขึ้นในngAfterViewInit
ตะขอซึ่งเกิดขึ้นเป็นส่วนหนึ่งของการตรวจจับการเปลี่ยนแปลงเริ่มต้น ซึ่งในตัวมันเองไม่มีปัญหา - ปัญหาคือsetMessage()
การเปลี่ยนแปลงการโยง แต่ไม่ทริกเกอร์การตรวจจับการเปลี่ยนแปลงรอบใหม่หมายความว่าการเปลี่ยนแปลงนี้จะไม่ถูกตรวจพบจนกว่าการตรวจจับการเปลี่ยนแปลงรอบในอนาคตจะถูกเรียกใช้ที่อื่น
Takeaway: สิ่งใดก็ตามที่เปลี่ยนแปลงการโยงจำเป็นต้องกระตุ้นการตรวจจับการเปลี่ยนแปลงรอบเมื่อมันทำ
อัปเดตเพื่อตอบสนองต่อคำขอทั้งหมดสำหรับตัวอย่างของวิธีการดังกล่าว : โซลูชันของ @ Tycho ทำงานได้เช่นเดียวกับสามวิธีในคำตอบ @MarkRajcok แต่ตรงไปตรงมาพวกเขาทุกคนรู้สึกน่าเกลียดและผิดกับฉันเช่นประเภทของแฮ็คที่เราคุ้นเคยในการ ng1
เพื่อให้แน่ใจว่ามีบางครั้งกรณีที่แฮ็กเหล่านี้มีความเหมาะสม แต่ถ้าคุณกำลังใช้พวกเขาในอะไรมากกว่ามากพื้นฐานเป็นครั้งคราวก็เป็นสัญญาณว่าคุณกำลังต่อสู้กรอบมากกว่าอย่างเต็มที่กอดธรรมชาติปฏิกิริยาของมัน
IMHO, สำนวนที่มากขึ้น, "ทาง Angular2" ของการเข้าใกล้นี้เป็นบางสิ่งบางอย่างตามแนวของ: ( เสียงดังปัง )
@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
ข้อผิดพลาดอธิบายพฤติกรรมในรายละเอียดที่ดี