更改数据时如何更新子元素?

时间:2018-02-16 01:59:30

标签: javascript d3.js

我构建这些元素......

$(EmbedAssembliesIntoApk)

...来自以下数据:

<svg>
  <g class="group">
    <text class="label">Hello</text>
  </g>
  <g class="group">
    <text class="label">World</text>
  </g>
</svg>

创建后,我会更改数据并再次运行[ { id: 'a', label: 'Hello' }, { id: 'b', label: 'World' }, ] 。但是文本不会更新。

代码https://jsfiddle.net/ginpei/r7b65fzt/

.data()

第二次,它会查看绑定到function render (data, container) { const group = container.selectAll('.group') .data(data, d => d.id) const entered = group.enter().append('g') .attr({ class: 'group' }) entered.append('text') .attr({ class: 'label' }) .attr({ y: (d, i) => 20 + i * 20}) const label = group.selectAll('.label') .text(d => d.label) } 的数据,但绑定到.group的数据不会更新。我预计数据将会第一次设置。

如何更新它们?

实际上,如果我为子元素添加.label,我发现它有效。

.data()

这是更新它们的正确方法吗?

以更简单的方式更新它们会很棒,因为我的实际代码有很多后代元素。

1 个答案:

答案 0 :(得分:3)

此处的解决方案非常简单:只需将selectAll更改为select

const label = group.select('.label')
    .text(d => d.label);

要理解原因,这是我用selectselectAll之间的差异制作的表格:

+--------------------+----------------------------------+----------------------------+
| Method             |              select()            |         selectAll()        |
+--------------------+----------------------------------+----------------------------+
| Selection          | selects the first element        | selects all elements that  |
|                    | that matches the selector string | match the selector string  |
+--------------------+----------------------------------+----------------------------+
| Grouping           | Does not affect grouping         | Affects grouping           |
+--------------------+----------------------------------+----------------------------+
| Data propagation   | Propagates data                  | Doesn't propagate data     |
+--------------------+----------------------------------+----------------------------+

注意传播数据传播数据

以下是您的代码更改和setTimeout更改数据:

&#13;
&#13;
// d3.js 3.x

const container = d3.select('body').append('svg')

function render(data, container) {
  const group = container.selectAll('.group')
    .data(data, d => d.id)

  const entered = group.enter().append('g')
    .attr({
      class: 'group'
    })
  entered.append('text')
    .attr({
      class: 'label'
    })
    .attr({
      y: (d, i) => 20 + i * 20
    })
  const label = group.select('.label')
    .text(d => d.label);

}

// first try
const data1 = [{
  id: 'a',
  label: 'Hello'
}, {
  id: 'b',
  label: 'World'
}, ]
render(data1, container)

// update
const data2 = [{
  id: 'a',
  label: 'Goodbye'
}, {
  id: 'b',
  label: 'Universe'
}, ]
setTimeout(function() {
  render(data2, container)
}, 1000)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

PS:您的代码无法使用v4(或v5)。