我创建了一个Angular服务来为用户导出SVGElement。简而言之,它会构建一个SVG并将符号附加到<defs>
。然后,服务使用Promise将此SVG返回给组件,然后组件将其复制到剪贴板或将其导出为文件。
我的问题是,在组件尝试将其导出时,导出的SVG元素为空。如果我在服务中的setTimeout()
周围插入resolve(svgElement)
,则可以使用。
我如何以更同步的方式操作这些动态生成的DOM元素? SVG永远不会为用户呈现。
这里是一些简化的代码,试图说明其功能。
\\ service.ts
public exportToSVG(ids: string[]): Promise<SVGElement> {
return new Promise((resolve, reject) => {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const defs = document.createElement('defs');
ids.forEach(async id => {
// use another method to get the symbol associated with the id
const symbol = await this._getSymbolByString(id);
defs.appendChild(symbol);
});
svg.appendChild(defs);
resolve(svg);
});
}
\\ component.ts
public copyToClipboard(ids: string[]) {
this.myService.exportToSVG(ids).then(svg => {
// this only copies `<svg><defs></defs></svg>`, unless a setTimeout is used
this.clipboardService.copyFromContent(svg.outerHTML);
});
}
\\ component.ts
public copyToClipboard(ids: string[]) {
this.myService.exportToSVG(ids).then(svg => {
this.clipboardService.copyFromContent(svg.innerHTML);
});
}
\\ service.ts
public exportToSVG(ids: string[]): Promise<SVGElement> {
return new Promise((resolve, reject) => {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const defs = document.createElement('defs');
let lengthIds = is.length;
let count = 0;
ids.forEach(async id => {
// use another method to get the symbol associated with the id
const symbol = await this._getSymbolByString(id);
defs.appendChild(symbol);
count++;
});
// check length of total number of elements in array and its count
if(count === lengthIds){
svg.appendChild(defs);
resolve(svg);
}
});
}
\\ component.ts
public copyToClipboard(ids: string[]) {
this.myService.exportToSVG(ids).then(svg => {
// this only copies `<svg><defs></defs></svg>`, unless a setTimeout is used
this.clipboardService.copyFromContent(svg.outerHTML);
});
}