Angular *ngIf 问题 HTML 元素在 JSPDF 生成 pdf 之前未完全呈现

Angular issue with *ngIf HTML elements are not completely rendered before JSPDF generate the pdf

你们好day/evening。

我目前遇到一个问题,在 jspdf 可以生成 pdf 之前,*ngIf 下的 HTML 元素没有完全加载。

与问题相关的.html文件

<div *ngIf="!templateHide" class="pdfPaper" id="printId">

    <div class='pdfLoop' *ngFor="let t of tempSplitArray">
    
    ...

    </div>

</div

这是 .ts 文件中的代码。

函数 getPdfDataList() 在生成之前处理数据。

await getPdfDataList(data){

  //*ngIf control
  this.templateHide = false;

  //this ensures the HTML render the element under *ngIf before continue the codes inside. 
  setTimeout(async ()=>{

      this.formId = 'printId';

      //handling data, tempSplitArray is being assigned inside here.
      let complete =  await this.getRawData(data);

      console.log(complete);

      this.generatePDF();

  },0);
}

生成 pdf 的函数 generatePdf()

generatePdf(){

  let formId = 'printId';

  //HTML DOM. I tried elementRef also but same result
  let htmLData = document.getElementById(formId);

  //the HTML DOM return correctly including the data
  console.log(htmLData);

  html2canvas(htmLData,{
            onclone: function(clonedDoc){
              clonedDoc.getElementById(formId).style.display = 'block';
            },scale: 2}).then(canvas => {

        //detect browser
        let browserName = this.browserName;

        let paddingTop = 24;
        let imgWidth = 210;
        let pageHeight = 297;
        let imgHeight = canvas.height * 210 / canvas.width;
        let heightLeft = imgHeight;
        let pdf = new jspdf('p', 'mm', 'a4');
        let position = paddingTop;

        const canvas4pdf = canvas.toDataURL("image/png");

        pdf.addImage(canvas4pdf , 'PNG', 0, position, imgWidth, imgHeight);
        heightLeft -= pageHeight;

        while(heightLeft > 1){
          position = heightLeft - imgHeight + paddingTop;
          pdf.addPage();
          pdf.addImage(canvas4pdf , 'PNG', 0, position, imgWidth, imgHeight);
          heightLeft -= pageHeight;
        }

        pdf.setProperties({title:this.titleCaseWord(this.formType)});


        if(browserName=='chrome'){
          //require blob for chrome view
          window.open(URL.createObjectURL(pdf.output("blob")));
        }else{
          pdf.output('dataurlnewwindow');
        }
  }
}

看来我输入的代码有误。以下是工作代码:

await getPdfDataList(data){

  //*ngIf control
  this.templateHide = false;
  this.formId = 'printId';

  //handling data, tempSplitArray is being assigned inside here.
  let complete =  await this.getRawData(data);
  console.log(complete);
 
  setTimeout(async ()=>{

      this.generatePDF();

  },0);

}

显然,数据必须与 *ngIf 开关一起完全呈现。之后调用setTimeout可以帮助刷新*ngIf下的元素,包括丢失的数据。