ค้นหาเว็บไซต์

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

บทความที่เกี่ยวข้อง