javascript - 渲染后从组件获取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 完成渲染组件。有什么办法吗?
提前致谢。
解决方案
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));
});
});
推荐阅读
- c# - C# DataTable csv IndexOutOfRangeException
- python - 如何处理xgboost分类器的过拟合?
- lambda - Stream API:从同一对象中收集基于另一个属性条件的属性列表
- django - 我在使用 docker nginx 和 gunicorn 部署我的 django 项目时遇到问题
- sql - 对 2 列求和并合并行
- java - 为什么我们必须在 Java 中的 if 语句之外声明变量
- php - iFrame - 退出全屏的问题
- python - 如何将只有日期和月份列的数据框解析为具有 pd.datetime 格式的新列?
- python - 删除 txt 文件中某些行中的结束/尾随逗号
- c# - 使用 API 自动发布事件,日期和时间不正确