You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 6中D3.js树形图点击展开/收缩功能报错排查

Angular 6 + D3.js v4树形图点击节点报错this.update is not a function的解决方案

我之前也碰到过完全一样的问题!你遇到的这个错误本质是D3事件回调里的this上下文不对——当点击节点时,D3会把this指向触发事件的DOM节点,而不是你的Angular组件实例,所以自然找不到update方法,类里的其他字段也会变成undefined。

下面给你几个直接适配你代码的解决办法:

方法1:用箭头函数包裹点击事件回调

在绑定点击事件的nodeEnter代码块里,把原来的this.click改成箭头函数形式,这样就能保留组件的this上下文:

let nodeEnter = node.enter().append("g")
  .attr("class", "node")
  .attr("transform", d => "translate(" + source.y0 + "," + source.x0 + ")")
  .on("click", (event, d) => this.click(d)); // 这里改为箭头函数包裹

注意D3 v4的事件回调参数顺序是(event, d),第一个是事件对象,第二个是节点数据,要对应正确。

方法2:把click方法定义成箭头函数

直接将组件内的click方法改成箭头函数形式,这样不管怎么调用它,this都会固定指向组件实例:

click = (d) => {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  this.update(d);
}

这种方法更彻底,不用修改事件绑定代码,直接从方法定义层面锁定this的指向。

方法3:用bind强制绑定上下文

如果你习惯用普通函数写法,也可以在绑定事件时用bind把组件的this传进去:

.on("click", this.click.bind(this));

不过这种方法要注意:bind会返回新的函数,后续如果需要解绑事件可能会有麻烦,所以前两种方法更推荐。

问题根源说明

在JavaScript中,普通函数的this指向由调用它的上下文决定。D3触发点击事件时,会把回调函数的this设置为触发事件的DOM元素(也就是节点对应的<g>标签),此时this不再是你的DataDisplayerComponent实例,自然访问不到update方法。而箭头函数不会创建自己的this,它会继承外层作用域的this(也就是组件实例),所以就能正常调用this.update了。

随便选一种方法修改后,点击节点的展开/收缩功能就能正常工作啦!

内容的提问来源于stack exchange,提问作者izb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:27:05