簡體   English   中英

在 Angular 中操作未渲染的 DOM 元素以進行導出

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM