有没有办法做类似的事情:
<div [innerHTML]="content" (innerHTMLchange)="contentInit()"></div>
正如我的代码所在,我有一个变量content
,它从一个从我的快递服务器获取字符串的服务更新。设置内容变量,并在网站加载时更新innerHTML。现在我有一个javascript库需要对添加的字符串调用innerHTML。我目前遇到的问题是在更新HTML之前调用了contentInit()
。
constructor(private service: StringService) {
this.service.getString().subscribe((string) => {
this.content = string;
this.contentInit(); // called before innerHTML changes
});
}
contentInit: void {
var innerHTMLDiv = document.getElementById("innerHTML-div");
//do stuff
}
如果模板可以在innerHTML发生变化时调用contentInit()
,那么应解决我的问题,因为innerHTML将被启动并且它可以连接到元素。
答案 0 :(得分:1)
只需显式调用更改检测,而不是等待Angular运行下一个周期:
constructor(private service: StringService, cdRef:ChangeDetectorRef) {
this.service.getString().subscribe((string) => {
this.content = string;
cdRef.detectChanges(); // after that the DOM is updated
this.contentInit(); // called before innerHTML changes
});
}
答案 1 :(得分:0)
重播可能为时已晚,但希望帮助某人,或者更好地了解。
如果你想将一些脚本应用到更新的innerHtml,你可以调用setTimeout(() => contentInit(), 0)
来加载js一次,在tick完成html渲染之后
this.service.getString().subscribe((string) => {
this.content = string;
setTimeout(() => contentInit(), 0)
});
innerHtml
将在this.content = string;
之后通过同步过程呈现
而contentInit()将在下一个时间点开始工作。
直接的想法是使用AfterViewInit。 你需要把
import { AfterViewChecked } from '@angular/core';
export class YourComponent implements AfterViewChecked {
private js_loaded = false;
constructor(private service: StringService, cdRef:ChangeDetectorRef) {
this.service.getString().subscribe((string) => {
this.js_loaded = false;
this.content = string;
});
}
ngAfterViewChecked() {
if (!this.loaded && document.getElementById("innerHTML-div")) {
this.js_loaded = true;
this.contentInit();
}
}
}
document.getElementById("innerHTML-div")
正在测试已经呈现的HTML,您可以使用内容中的任何选择器。
如果要在HTML中触发js,可以尝试放置隐藏标记
<div *ngIf="content">{{contentInit()}}</div>
或<div *ngIf="content"><div *ngIf="contentInit()"></div></div>
但这种方式并不优雅,只要内容更新,contentInit()
就会多次加载。这也需要一个if块来测试更改到另一个页面时更改内容。