Angular 7 和 html2Canvas 使用 foreach 迭代数组总是下载最后找到的索引
Angular 7 and html2Canvas iterating an array using foreach always download the last found index
我正在 typescript 中遍历一个数组来拍摄一个 div 的快照,其 id 等于数组的索引并下载一个图像文件。
如果数组有 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>
我尝试在 forEach()
:
中使用 while
public toCanvas() {
let i = Object.keys(this.array).length;
Object.keys(this.array).forEach((key, index) => {
while (i != -1) {
i--;
console.log(i)
var elem = document.getElementById(index.toString());
html2canvas(elem).then(function (canvas) {
var generatedImage = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
window.location.href = generatedImage;
});
}
})
}
它正在执行相同的行为。它控制索引直到达到 0
,然后下载最后检测到的图像 <mat-card>
编辑
这里有一个stackblitz@xyz提供的递归方法
您的实现可能不同,请相应地更改代码。考虑数组中的元素是这样的:array = [0, 1, 2];
。而数组中的元素就是你要下载的div个id。所以你的 div 就像:
<div [id]="id" *ngFor="let id of array">
I am div id: {{id}}
</div>
实施 1
您可以利用 rxjs
按顺序下载 div,让数组成为 Observable 并在开始下一次下载之前处理数组中的每个值(将使用 concatMap
这个)。
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);
})
}
你的 HTML 有这个按钮来触发呼叫:
<button (click)="downloadDivs()">Download divs using rxjs</button>
实施 2
只有在一个 div 下载完成后才调用下一个 div
的下载。为此,我使用了 recursion
。
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)
});
}
}
请参阅此 link 以了解实施方式:https://stackblitz.com/edit/download-div-using-canvas?file=src%2Fapp%2Fapp.component.ts
我正在 typescript 中遍历一个数组来拍摄一个 div 的快照,其 id 等于数组的索引并下载一个图像文件。
如果数组有 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>
我尝试在 forEach()
:
while
public toCanvas() {
let i = Object.keys(this.array).length;
Object.keys(this.array).forEach((key, index) => {
while (i != -1) {
i--;
console.log(i)
var elem = document.getElementById(index.toString());
html2canvas(elem).then(function (canvas) {
var generatedImage = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
window.location.href = generatedImage;
});
}
})
}
它正在执行相同的行为。它控制索引直到达到 0
,然后下载最后检测到的图像 <mat-card>
编辑
这里有一个stackblitz@xyz提供的递归方法
您的实现可能不同,请相应地更改代码。考虑数组中的元素是这样的:array = [0, 1, 2];
。而数组中的元素就是你要下载的div个id。所以你的 div 就像:
<div [id]="id" *ngFor="let id of array">
I am div id: {{id}}
</div>
实施 1
您可以利用 rxjs
按顺序下载 div,让数组成为 Observable 并在开始下一次下载之前处理数组中的每个值(将使用 concatMap
这个)。
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);
})
}
你的 HTML 有这个按钮来触发呼叫:
<button (click)="downloadDivs()">Download divs using rxjs</button>
实施 2
只有在一个 div 下载完成后才调用下一个 div
的下载。为此,我使用了 recursion
。
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)
});
}
}
请参阅此 link 以了解实施方式:https://stackblitz.com/edit/download-div-using-canvas?file=src%2Fapp%2Fapp.component.ts