渲染后从组件获取 innerHTML
Get innerHTML from component AFTER render
我正试图从 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;
}
问题是我得到的内容before 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 完成组件渲染。有什么办法吗?
提前致谢。
尝试 AfterViewInit 生命周期钩子。是这样实现的
export class MyComponent implements AfterViewInit {
ngAfterViewInit() {
// code that should be executed after view initialization
}
}
您只需要使用 class 添加 AfterViewInit 生命周期挂钩。我还建议您在 OnInit 生命周期内分配 属性 。您的父组件应如下所示
export class appComponent implements OnInit, AfterViewInit{
ngOnInit(): void {
this.data = someData;
}
ngAfterViewInit(): void{
const svgCode = document.getElementById('my-component-id').innerHTML;
}
}
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,当你调用点击功能时,执行所有指令并“重绘”应用程序。因此,在第一种情况下,您试图在 Angular“重绘”之前获取 innerHTML。使用 setTimeout 你对 Angular 说:“嘿!你重画,然后,不要忘记进入 setTimeout 的指令” - 看到 setTimeout 没有毫秒 -
另一种方法是在构造函数中注入 ChangeDetectorRef 并在尝试获取 innerHTML
之前使用 markForCheck()
更新 另一个使用 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));
});
});
我正试图从 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;
}
问题是我得到的内容before 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 完成组件渲染。有什么办法吗?
提前致谢。
尝试 AfterViewInit 生命周期钩子。是这样实现的
export class MyComponent implements AfterViewInit {
ngAfterViewInit() {
// code that should be executed after view initialization
}
}
您只需要使用 class 添加 AfterViewInit 生命周期挂钩。我还建议您在 OnInit 生命周期内分配 属性 。您的父组件应如下所示
export class appComponent implements OnInit, AfterViewInit{
ngOnInit(): void {
this.data = someData;
}
ngAfterViewInit(): void{
const svgCode = document.getElementById('my-component-id').innerHTML;
}
}
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,当你调用点击功能时,执行所有指令并“重绘”应用程序。因此,在第一种情况下,您试图在 Angular“重绘”之前获取 innerHTML。使用 setTimeout 你对 Angular 说:“嘿!你重画,然后,不要忘记进入 setTimeout 的指令” - 看到 setTimeout 没有毫秒 -
另一种方法是在构造函数中注入 ChangeDetectorRef 并在尝试获取 innerHTML
之前使用markForCheck()
更新 另一个使用 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));
});
});