TypeScript - Angular 9 ตัวแปรไม่อัปเดตในมุมมอง
ฉันมีตัวแปรใน Component ของฉันที่มันกำลังอัปเดตขณะใช้ console.log(variable) แม้ว่ามันจะไม่อัปเดตใน View ของฉันเมื่อใช้ {{ variable }} ฉันได้ลองทำหลายอย่างแล้ว ตัวเลือกสุดท้ายของฉันคือการใช้ Observers แต่ก็ยังไม่ทำงานอย่างที่ควรจะเป็น
ฉันจะอธิบายโค้ดของฉัน:
ดังนั้นฉันมีบริการ หน่อส่วนฐาน หน่อส่วนแอป และส่วนประกอบอื่น
คอมโพเนนต์ฐานของฉันไม่มีหน้าตาเลย มันเพียงแค่สร้างอินสแตนซ์ของเซอร์วิสเท่านั้น เช่นนี้:
private _communicationService: CommunicationService;
private _clientService: ClientService;
constructor(private injector : Injector) {
this.clientService = this.injector.get(ClientService);
}
(รวมถึงเก็ตเตอร์และเซ็ตเตอร์)
คอมโพเนนต์แอปของฉันและคอมโพเนนต์อีกตัวหนึ่ง ขยายจาก BaseComponent
สิ่งที่ฉันคิดว่าผิดพลาดในการทำงานของฉันคือสิ่งต่อไปนี้:
คอมโพเนนต์แอปของฉันกำลังเรียกฟังก์ชัน window ที่ฉันพยายามจะนำไปใช้ใน ngInit ของฉัน
export class AppComponent extends BaseComponent implements OnInit{
constructor(injector : Injector) {
super(injector);
}
ngOnInit(): void {
window.FlashExternalInterface.logLoginStep = (step : string) => {
this.clientService.loadClientProgress(step);
}
}
}
ส่วนประกอบ "อื่น" ของฉัน:
export class LoaderComponent extends BaseComponent implements OnInit {
public progress = 0;
constructor(injector : Injector) {
super(injector);
}
ngOnInit(): void {
this.clientService.clientProgress.subscribe(data => {
console.log("Data Changing?: " + data);
this.progress = data;
console.log("Progress changing??" + this.progress);
});
}
}
ตัวแปร progress ของฉันเปลี่ยนแปลงในคอนโซล F12 แต่ไม่เปลี่ยนแปลงในมุมมอง
ฉันได้ลองใช้ {{ this.progress }} และโดยไม่ใช้ this. หรือแม้แต่เรียกอินสแตนซ์เซอร์วิสโดยตรงจาก Base Component clientService.clientProgress.getValue()
ผมหมายถึง ฟังก์ชัน window มันกำลังให้ผมเจอข้อผิดพลาดในคอนโซลแบบ:
ERROR TypeError: Cannot set property 'logLoginStep' of undefined.
แต่ถึงอย่างนั้น ตัวแปรก็ยังเปลี่ยนในคอนโซล ตัวแปรคอนโซล
คำตอบ #1
นี่น่าจะเป็นปัญหาแบบอะซิงโครนัส เนื่องจาก progress ถูกกำหนดค่าภายในคำสั่ง subscribe() ก่อนที่ข้อมูลจะกลับมาจากบริการของไคลเอนต์ progress จะยังไม่ได้รับการอัปเดต
เหตุผลที่ console.log ของคุณทำงานได้เพราะมันอยู่ภายในบล็อก subscribe() ของคุณ ดังนั้นโดยนิยามแล้วมันจึงรอให้บริการส่งค่ากลับก่อนที่จะบันทึกลงในคอนโซล ในขณะเดียวกัน HTML ของคุณถูกสั่งให้แสดงค่าปัจจุบันของ progress ทันทีที่หน้าโหลดเสร็จ แม้ว่าจะเรียกใช้ subscribe() ภายใน ngOnInit() แต่ก็ยังต้องใช้เวลาที่ไม่เป็นศูนย์ในการที่บริการจะส่งค่าที่อัปเดตกลับมา ซึ่งโดยตอนนั้นมันก็สายไปแล้ว
มีหลายวิธีในการจัดการเรื่องนี้ใน HTML ของคุณ
ท่อ async
<p>{{ progress | async }}<p>นี่จะตรวจสอบตัวแปร progress สำหรับการอัปเดตและแสดงการเปลี่ยนแปลงไปยัง DOM โดยตรงเมื่อค่าถูกอัปเดต; ซึ่งจริง ๆ แล้วเหมือนกับสิ่งที่ .subscribe() ทำในไฟล์ .ts ของคุณ
*ngIf
<p *ngIf="progress">{{ progress }}</p>นี่จะไม่แสดงผล <p> เลยจนกว่า ตัวแปร progress จะมีค่าเป็นจริง กล่าวคือ ในกรณีนี้จะไม่ใช่ 0 null หรือ undefined