使用selection.select防止不需要的数据继承

时间:2013-07-24 23:54:54

标签: d3.js

在d3中,selection.select具有从原始选择中的父节点继承数据的副作用。在父节点和子节点之间共享数据的情况下,这是理想的,这样绑定到父节点的更新数据将被推送到子节点,而不需要在每个级别都进行数据连接。

但是,绑定到父级的数据与绑定到子级的数据之间明确没有关系的情况呢?在这种情况下,selection.select可能是阴险的,因为只需选择一个节点就可以使该节点的数据被无关的父数据破坏。

避免这种情况的最佳方法是什么?我可以想到几个选项,但看起来都不是很好:

  1. 除了需要隐式数据继承的情况外,始终在任何地方使用selection.selectAll。但是,这并不理想,因为它使selection.selectd3.select不一致,而selection.select仅用于选择单个节点(正是我想对d3.select执行的操作)。

  2. 使用selection.selectdescendents selector代替selection.select隔离特定节点。使用selection.update(selector)的方便之处在于它隐含地将选择限制为起始选择的后代。使用选择器实现这一目标并不是那么好。

  3. 就个人而言,我并不是在API中使用一些最常用函数的特定形式的DOM状态修改副作用的狂热粉丝。我想如果selection.append之类的显式调用与selection.insertselection.select对称,我会发现更容易理解。

    但是在当前的API中,我想知道在使用{{1}}时是否还有其他机制可以用来有效地破坏继承?

2 个答案:

答案 0 :(得分:1)

我最终在D3 Github上提交了一个问题:https://github.com/mbostock/d3/issues/1443。没有任何解决方案,但有一个(我认为)有趣的讨论问题。在最底层,Mike确实提供了一种可行的解决方法,为方便起见,我将在此处粘贴:

  

不是一个好的答案,但是一种阻止数据继承的方法是让一个中间节点没有绑定数据。

var intermediary = selection.append("div")
    .datum(function() { return null; });
     

然后,来自中介的任何选择都不会传播来自父选择的数据。但是,当然,DOM中的中间节点有点不幸。

答案 1 :(得分:0)

您可以使用:

d3.select(selection.node().querySelector(selector))

使用selectWithoutDataPropagation()方法扩展选择原型的jsfiddle中的实际操作。