首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular2、ZoneJS和外部更改的DOM

Angular2、ZoneJS和外部更改的DOM
EN

Stack Overflow用户
提问于 2016-05-27 14:11:52
回答 3查看 888关注 0票数 3

我需要一些关于Angular2 RC1 web应用程序中外部变化的DOM的帮助。场景很简单:我确实有一个组件,其中包含一个带有ID的空div,如下所示

代码语言:javascript
复制
<div id="my-svg-canvas"></div>

类型化组件有一个ngOnInit方法,该方法从普通JS文件中触发一个函数,该文件通过index.html中的脚本标记包含。该函数将SVG呈现到上面列出的"div“标记中。SVG包含一些带有单击指令的a-元素,这些指令引用了组件中的几个方法。

在SVG完全编写之后调用$scope.$apply()之后,这在当时的$scope.$apply中运行得很好。现在,在Angular2中,没有触发组件中的各个方法。

我知道,ZoneJS现在负责检测DOM中的更改。我希望这是自动完成的整个DOM呈现在一个角管理的组件。接下来的尝试是在组件中注入NgZone并显式地在其中运行呈现函数,如下所示:

代码语言:javascript
复制
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框架,如下所示:

代码语言:javascript
复制
function renderSVG(dataParam, elementIdParam) {
  draw = SVG(elementIdParam).spof();
  initAndPaint(draw, dataParam);
  return draw; 
 }

和由SVG.js库生成的标记。

代码语言:javascript
复制
<a id="SvgjsA1033" on-click="showVal('W1')" class="union">

当我将生成的SVG代码粘贴到模板中时,一切正常。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-27 17:35:18

我不认为角将解析你的动态添加的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

票数 3
EN

Stack Overflow用户

发布于 2016-05-27 14:13:44

我会将您的代码移到组件的ngAfterViewInit钩子方法中:

代码语言:javascript
复制
ngAfterViewInit() {
  this.ngZone.run(() => {renderSVG(this.myData, "my-svg-canvas");})
}

此外,您应该使用ViewChild装饰器引用DOM元素:

代码语言:javascript
复制
<div #mySvgCanvas"></div>

代码语言:javascript
复制
@ViewChild('mySvgCanvas')
mySvgCanvasElt: ElementRef;

ngAfterViewInit() {
  var elt = this.mySvgCanvasElt.nativeElement;

我不认为这里需要明确地使用区域.

票数 2
EN

Stack Overflow用户

发布于 2016-05-28 08:44:12

Mark的链接(请参阅“关于更复杂的方法”)可以在接受的答案中使用DynamicLoaderComponent的解决方案。作为这个线程的闭包,这是我的实现:

代码语言:javascript
复制
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);
 }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37485672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档