จากเอกสาร:
detectChanges (): เป็นโมฆะ
ตรวจสอบเครื่องมือตรวจจับการเปลี่ยนแปลงและลูก ๆ ของมัน
หมายความว่าหากมีกรณีที่สิ่งใดในโมเดลของคุณ (คลาสของคุณ) เปลี่ยนไป แต่มันไม่ได้สะท้อนมุมมองคุณอาจต้องแจ้ง Angular เพื่อตรวจสอบการเปลี่ยนแปลงเหล่านั้น (ตรวจจับการเปลี่ยนแปลงในท้องถิ่น) และอัปเดตมุมมอง
สถานการณ์ที่เป็นไปได้อาจเป็น:
1- ตัวตรวจจับการเปลี่ยนแปลงถูกแยกออกจากมุมมอง (ดูตัวถอด )
2- มีการอัปเดตเกิดขึ้น แต่ไม่ได้อยู่ในโซนแองกูลาร์ดังนั้นแองกูลาร์จึงไม่ทราบ
เช่นเมื่อฟังก์ชั่นของบุคคลที่สามปรับปรุงโมเดลของคุณและคุณต้องการอัปเดตมุมมองหลังจากนั้น
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
เนื่องจากรหัสนี้อยู่นอกโซนของ Angular (อาจเป็นไปได้) คุณส่วนใหญ่จำเป็นต้องตรวจสอบการเปลี่ยนแปลงและอัปเดตมุมมองดังนี้:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
บันทึก :
มีวิธีอื่นในการทำงานข้างต้นกล่าวอีกนัยหนึ่งมีวิธีอื่นที่จะนำการเปลี่ยนแปลงนั้นมาใช้ในวงจรการเปลี่ยนแปลงเชิงมุม
** คุณสามารถห่อฟังก์ชั่นของบุคคลที่สามภายใน zone.run:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** คุณสามารถห่อฟังก์ชั่นภายใน setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- นอกจากนี้ยังมีกรณีที่คุณอัปเดตโมเดลหลังจากchange detection cycle
เสร็จสิ้นซึ่งในกรณีเหล่านั้นคุณได้รับข้อผิดพลาดที่น่ากลัวนี้:
"นิพจน์เปลี่ยนไปหลังจากตรวจสอบแล้ว";
โดยทั่วไปหมายถึง (จากภาษา Angular2):
ฉันเห็นการเปลี่ยนแปลงในแบบจำลองของคุณที่เกิดจากหนึ่งในวิธีที่ฉันยอมรับ (เหตุการณ์, คำขอ XHR, setTimeout, และ ... ) จากนั้นฉันก็ตรวจจับการเปลี่ยนแปลงเพื่ออัปเดตมุมมองของคุณและฉันก็ทำเสร็จแล้ว ฟังก์ชั่นในรหัสของคุณซึ่งปรับปรุงโมเดลอีกครั้งและฉันไม่ต้องการเรียกใช้การตรวจจับการเปลี่ยนแปลงอีกครั้งเพราะไม่มีการตรวจสอบที่สกปรกเหมือน AngularJS อีกต่อไป: D และเราควรใช้การไหลของข้อมูลทางเดียว!
คุณจะพบข้อผิดพลาดนี้อย่างแน่นอน: P
สองสามวิธีในการแก้ไข:
1- วิธีที่เหมาะสม : ตรวจสอบให้แน่ใจว่าการอัปเดตนั้นอยู่ในวงจรการตรวจจับการเปลี่ยนแปลง (การอัปเดต Angular2 เป็นวิธีหนึ่งที่เกิดขึ้นเพียงครั้งเดียวอย่าอัปเดตโมเดลหลังจากนั้นและย้ายรหัสของคุณไปยังสถานที่ / เวลาที่ดีขึ้น
2- วิธีขี้เกียจ : เรียกใช้ detectChanges () หลังจากการอัปเดตนั้นจะทำให้ angular2 มีความสุขนี่ไม่ใช่วิธีที่ดีที่สุด แต่เมื่อคุณถามว่าสถานการณ์เป็นไปได้อย่างไรนี่เป็นหนึ่งในนั้น
วิธีนี้คุณจะพูดว่า: ฉันรู้ว่าคุณตรวจจับการเปลี่ยนแปลงอย่างจริงใจ แต่ฉันต้องการให้คุณทำอีกครั้งเพราะฉันต้องอัปเดตบางอย่างได้ทันทีหลังจากที่คุณตรวจสอบเสร็จ
3- ใส่รหัสใน a setTimeout
, เพราะได้setTimeout
รับการแก้ไขโดยโซนและจะทำงานdetectChanges
หลังจากเสร็จสิ้น
จากเอกสาร
markForCheck() : void
ทำเครื่องหมายบรรพบุรุษบรรพบุรุษ ChangeDetectionStrategy ทั้งหมดที่จะตรวจสอบ
นี้เป็นสิ่งจำเป็นส่วนใหญ่เมื่อChangeDetectionStrategyของคอมโพเนนต์ของคุณเป็นOnPush
OnPush หมายความว่าให้รันการตรวจจับการเปลี่ยนแปลงหากสิ่งเหล่านี้เกิดขึ้น:
1- หนึ่งใน @inputs ขององค์ประกอบได้ถูกแทนที่อย่างสมบูรณ์ด้วยค่าใหม่หรือเพียงแค่ใส่ถ้าการอ้างอิงของคุณสมบัติ @Input มีการเปลี่ยนแปลงทั้งหมด
ดังนั้นหากChangeDetectionStrategyของคอมโพเนนต์ของคุณคือOnPushแล้วคุณมี:
var obj = {
name:'Milad'
};
จากนั้นคุณอัปเดต / กลายพันธุ์เช่น:
obj.name = "a new name";
นี่จะไม่อัปเดตการอ้างอิงobjดังนั้นการตรวจจับการเปลี่ยนแปลงจะไม่ถูกเรียกใช้ดังนั้นมุมมองไม่ได้สะท้อนการปรับปรุง / การกลายพันธุ์
ในกรณีนี้คุณต้องบอก Angular ด้วยตนเองเพื่อตรวจสอบและอัปเดตมุมมอง (markForCheck)
ดังนั้นถ้าคุณทำสิ่งนี้:
obj.name = "a new name";
คุณต้องทำสิ่งนี้:
this.cd.markForCheck();
ค่อนข้างด้านล่างจะทำให้การตรวจจับการเปลี่ยนแปลงทำงาน:
obj = {
name:"a new name"
};
ที่สมบูรณ์แทนที่ obj ก่อนหน้านี้มีใหม่{}
;
2- เหตุการณ์ถูกไล่ออกเช่นคลิกหรืออะไรทำนองนั้นหรือองค์ประกอบย่อยใด ๆ ที่ทำให้เกิดเหตุการณ์
กิจกรรมที่ชอบ:
- คลิก
- keyup
- กิจกรรมการสมัครสมาชิก
- เป็นต้น
ดังนั้นในระยะสั้น:
ใช้detectChanges()
เมื่อคุณอัปเดตโมเดลหลังจากแองกูลาร์แล้วมันเป็นการตรวจจับการเปลี่ยนแปลงหรือหากการอัปเดตไม่ได้อยู่ในโลกเชิงมุมเลย
ใช้markForCheck()
หากคุณกำลังใช้ OnPush และคุณอ้อมChangeDetectionStrategy
โดยกรรมวิธีข้อมูลบางส่วนหรือคุณอัปเดตรูปแบบภายในsetTimeout ;