首页 > 解决方案 > 渲染后从组件获取innerHTML

问题描述

我试图从 DOM 中“窃取”由自己的组件生成的 SVG 代码。我这样做:

<my-own-component id="my-component-id" #myComponentId
                        [data]="data"></my-own-component>
onButtonClick() {
   this.data = someData;
   const svgCode = document.getElementById('my-component-id').innerHTML;
}

也试过(也没有工作):

@ViewChild('myComponentId') myComponentId;
...
onButtonClick() {
   this.data = someData;
   const svgCode = this.myComponentId.nativeElement.children[0].innerHTML;
}

问题是我在Angular 应用由 引起的更改之前this.data = someData获取了内容,因此不包括 SVG 的元素。我已经“解决”了它引入了 50 毫秒的超时。这有效,但不是正确的解决方案,是一个糟糕的补丁:

this.data = someData;        
await new Promise(resolve => setTimeout(resolve.bind(null, null), 50));
const svgCode = document.getElementById('my-component-id').innerHTML;

我希望能够等待 Angular 完成渲染组件。有什么办法吗?

提前致谢。

标签: javascriptangulartypescriptionic-frameworkcapacitor

解决方案


Elezan,问题是你需要“让 Angular 喘口气”。如果你有,例如

<div>{{data}}</div>
click(){
  this.data="......."
  //here you don't can check the value of innerHtml
}

这个“呼吸”是使用 setTimeout

<div>{{data}}</div>
click(){
  this.data="......."
  setTimeout(()=>{
     //now here you can check the value of innerHtml
  })
}

认为 Angular,当您调用 click 函数时,执行所有指令并“重新绘制”应用程序。因此,在第一种情况下,您试图在 Angular“重绘”之前获取 innerHTML。使用 setTimeout 您对 Angular 说:“嘿!您重新绘制,然后不要忘记 setTimeout 中的说明” - 看到 setTimeout 没有毫秒 -

另一种方法是在构造函数ChangeDetectorRef中注入并markForCheck()在尝试获取 innerHTML 之前使用

更新另一个使用 observables 的例子

$observable.subscribe(res=>{
    this.data=res
    setTimeout(()=>{
         ..get the innerHTML
    })
})

或者承诺

$promise.then(
  res=>{
    this.data=res
    setTimeout(()=>{
         ..get the innerHTML
    }),
  err=>{...}
)

或者await

const svgCode = await new Promise<string>(resolve => { 
    setTimeout(() => {
        resolve(document.getElementById('my-component-id').innerHTML));
    });  
}); 


推荐阅读