繁体   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