[英]Manipulating unrendered DOM elements for export in Angular
我創建了一個 Angular 服務來為用戶導出一個 SVGElement。 簡單地說,它構建了一個 SVG 並將符號附加到<defs>
。 然后,該服務使用 Promise 將此 SVG 返回到組件,然后組件將其復制到剪貼板或將其導出為文件。
我的問題是導出的 SVG 元素在組件嘗試導出它時為空。 如果我在服務中的resolve(svgElement)
周圍插入一個setTimeout()
,它就可以工作。
如何以更同步的方式操作這些動態生成的 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);
});
}
嘗試使用 innerHTML 代替:
\\ component.ts
public copyToClipboard(ids: string[]) {
this.myService.exportToSVG(ids).then(svg => {
this.clipboardService.copyFromContent(svg.innerHTML);
});
}
Angular 具有異步特性。 當您應用 Foreach 循環時,angular 不會等待響應並執行下一個操作,這就是您無法獲取defs
變量的原因。 您應該將此代碼放入 foreach 循環完成后觸發的條件中。
\\ 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); }); }
所以我認為它對你有用。
我通過鏈接 Promises 解決了這個問題,而不是使用異步...等待。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.