我需要一些关于Angular2 RC1网络应用程序中外部更改的DOM的帮助。场景很简单:我确实有一个带有相应模板的组件,其中包含一个带有这样的ID的空div
<div id="my-svg-canvas"></div>
typescripted组件有一个ngOnInit方法,它从一个普通的JS文件中触发一个函数,该文件通过index.html中的script-tag包含在内。该函数将SVG呈现为上面列出的“div”标记。 SVG包含一些带有on-click指令的a元素,这些指令引用了我的组件中的几个方法。
在调用$ scope后,在Angular1中工作正常。在完全写入SVG后,$ apply()。现在,在Angular2中,我的组件中的各个方法不会被触发。
我知道,ZoneJS现在负责检测DOM中的变化。我希望这是在Angular管理的组件内呈现的整个DOM自动完成的。接下来尝试在我的组件中注入NgZone并在其中显式运行渲染函数,如下所示:
ngOnInit() {
this.ngZone.run(() => {renderSVG(this.myData, "my-svg-canvas");})
}
也没有成功: - /此外,我注册了一个MutationObserver(请参阅此主题:Angular2 Directive: How to detect DOM changes),因为问题发生的情况与我有点类似。但它也没有解雇。
我不知道在哪里寻找,没有错误信息要坚持: - ???
注意:由于SVG渲染框架拒绝设置无效属性,因此必须使用“on-click”而不是“(click)”。显然,以括号开头的属性适用于HTML,但不适用于XML。但是,这不应该是问题,因为这两个指令都是完全可以交换的。
PS:
调用的呈现方法使用SVG.js框架,如下所示:
function renderSVG(dataParam, elementIdParam) {
draw = SVG(elementIdParam).spof();
initAndPaint(draw, dataParam);
return draw;
}
由SVG.js lib生成的标签
<a id="SvgjsA1033" on-click="showVal('W1')" class="union">
当我将生成的SVG代码粘贴到我的模板中时,一切正常。
答案 0 :(得分:2)
我不认为Angular会解析动态添加的HTML(请参阅Angular2 - catch/subscribe to (click) event in dynamically added HTML)。
因此,在您调用renderSVG()
之后,您可能需要遍历DOM并找到新添加的a
元素,然后为每个元素手动添加(以后删除)事件处理程序之一。
请参阅Dynamically add event listener in Angular 2。
有关更具参与性的方法,请参阅Equivalent of $compile in Angular 2。
答案 1 :(得分:1)
我会将您的代码移动到组件的ngAfterViewInit
挂钩方法中:
ngAfterViewInit() {
this.ngZone.run(() => {renderSVG(this.myData, "my-svg-canvas");})
}
此外,您应该使用ViewChild
装饰器引用您的DOM元素:
<div #mySvgCanvas"></div>
和
@ViewChild('mySvgCanvas')
mySvgCanvasElt: ElementRef;
ngAfterViewInit() {
var elt = this.mySvgCanvasElt.nativeElement;
我认为这里不需要明确使用区域......
答案 2 :(得分:1)
Mark Rajcok的链接(参见&#34;对于更复杂的方法&#34;)在接受的答案中使用DynamicLoaderComponent
的解决方案。作为这个线程的闭包,这是我的实现:
constructor(private loader: DynamicComponentLoader, private injector:Injector) {}
ngAfterViewInit() {
let tournamentCanvas = document.createElement("canvas");
renderKOTournamentSVG(this.tournament, tournamentCanvas);
@Component({
selector: 'canvas-component',
template: tournamentCanvas.outerHTML)}
class CanvasComponent {}
this.loader.loadAsRoot(CanvasComponent, "canvas-component", this.injector);
}