Angular 7和html2Canvas使用foreach迭代数组时始终下载最后找到的索引

Angular 7和html2Canvas使用foreach迭代数组时始终下载最后找到的索引,angular,typescript,typescript2.0,html2canvas,angular7,Angular,Typescript,Typescript2.0,Html2canvas,Angular7,我在typescript中迭代一个数组,以获取id等于数组索引的div的快照,并下载一个图像文件 如果阵列有2行,则应下载2个图像。以下是脚本: public toCanvas() { let i = Object.keys(this.array).length; Object.keys(this.array).forEach((key, index)=>{ var elem = document.getElementById(index.t

我在typescript中迭代一个数组,以获取id等于数组索引的div的快照,并下载一个图像文件

如果阵列有2行,则应下载2个图像。以下是脚本:

public toCanvas() {
    let i = Object.keys(this.array).length;

    Object.keys(this.array).forEach((key, index)=>{
               var elem = document.getElementById(index.toString());

console.log(index)
      html2canvas(elem).then(function(canvas) {
        var generatedImage = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
        window.location.href=generatedImage;
      });


    })
  }
使用
Object.keys(this.array).forEach((key,index)
,我迭代获取索引,然后查找文档
getElementId(index)

问题是它总是下载最后一张图片

在控制台上,索引在开始时被控制台化,然后图像被下载:

html脚本:

<mat-card [id]="i"  *ngFor="let arrayOfData of array; let i=index; "  class="example-card"  #matCard>
它也在做同样的事情。它会操纵索引,直到它达到
0
,然后下载最后检测到的

编辑


以下是@xyz提供的递归方法的一个示例。

您的实现可能不同,请相应地更改代码。考虑到数组中的元素如下:
数组=[0,1,2];
。数组中的元素是要下载的div的ID。因此,您的div如下所示:

<div [id]="id" *ngFor="let id of array">
  I am div id: {{id}}
</div>
您的HTML具有以下按钮来触发调用:

<button (click)="downloadDivs()">Download divs using rxjs</button>

有关实现,请参见此链接:

我认为用
let
替换
var
可以解决您的问题,但我不认为您应该这样做。永远不要在循环中运行异步调用。@xyz好的。您能告诉我怎么做吗?@xyz我是说异步calls@xyz它不适用于
var
Lil busy,我将添加一个如果还没有回答,请稍后回答,您替换了什么?将
var elem=docum..
替换为
let elem=doc…
。它可以工作。
let
为变量提供块范围,因此每个循环都是一个新块,而
var
提供函数范围,以便相同的元素被重写,最后一个值被删除用于下载您的图像。也将
var generatedImage
替换为
let generatedImage
错误说明:
Error TypeError:html2canvas无法读取null的属性“ownerDocument”
我认为它从第一个实现就指向
docElem
,如果我控制台
这个数组,我将得到de>[Object Object]
而不是实值数组包含5个字段:
id
name
name\u other
gender
dob
。第二个实现没有正常工作,也没有读取
数组[index]。toString()
好的,太好了!实现取决于您。
  public downloadDivs() {
    from(this.array).pipe(
      concatMap((arrayElem) => {
        let docElem = document.getElementById(arrayElem.toString());
        return from(html2canvas(docElem).then(function (canvas) {
          let generatedImage = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
          let a = document.createElement('a');
          a.href = generatedImage;
          a.download = `${arrayElem}.png`;
          a.click();
          return `${arrayElem}.png`;
        }));
      })
    ).subscribe((imageName) => {
      console.log("Image downloaded", imageName);
    }) 
  }
<button (click)="downloadDivs()">Download divs using rxjs</button>
public trivialDownload() {
  console.log("Downloading image one by one, without a loop");
  this._download(0, this.array);
}

// this method will keep calling itself until all the elements of the array are scanned
private _download(index, array) {
  if (index >= array.length) {
    console.log("Done!")
  } else {
    let docElem = document.getElementById(array[index].toString());
      html2canvas(docElem).then((canvas) => {
        let generatedImage = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
        let a = document.createElement('a');
        a.href = generatedImage;
        a.download = `${array[index]}.png`;
        a.click();
        // at this point, image has been downloaded, then call the next download.
        this._download(index + 1, array)
      });
  }
}